/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "网格修改.h"

#include <节点/插座/通用插座.h>
#include <节点/插座/C_物体插座.h>
#include <节点/插座/C_单值矢量插座.h>
#include <节点/插座/C_数值插座.h>
#include <节点/插座/材质纹理插座.h>
#include <节点/插座/几何插座.h>
#include <节点/插座/list/list矢量插座.h>
#include <节点/插座/list/list物体插座.h>
#include <节点/插座/list/list数值插座.h>

#include <Context/当前默认操作数据.h>
#include <Context/数据创建销毁.h>

#include "节点/网格/几何网格.h"
#include "节点/socket_utils.h"
#include "节点/节点树.h"

#include "节点编辑.h"





static void f_多边形_销毁边(S_边* edge) {
	delete edge;
}

static uint32 f_多边形_边数量(S_边* edge) {
	return edge->edge.size();
}

static S_多边形元素* f_多边形_桥接(S_多边形* self, S_边* 边A, S_边* 边B) {
	if (!边A || !边B) return nullptr;
	return f_surface_多边形桥接(self, *边A, *边B);
}

static S_多边形元素* f_多边形_边采样(S_边* 边, const void* c采样系数, void* c采样坐标, void* c采样线向量) {
	auto& 采样系数 = *((std::vector<float32>*)c采样系数);
	auto& 采样坐标 = *((std::vector<vec3>*)c采样坐标);
	auto& 采样线向量 = *((std::vector<vec3>*)c采样线向量);
}

static S_多边形元素Array* f_多边形_复制(S_多边形* self, S_多边形元素* 元素, const S_Vec3Array* loc, const S_Vec3Array* rot, const S_Vec3Array* scal, uint32 num, uint8 合并元素) {
	if(num == -1) num = 1;
	S_多边形元素Array* 元素组 = (S_多边形元素Array*)f_core_array_new(num, sizeof(S_多边形元素*), true);

	bool 单例1 = loc->count < num;
	bool 单例2 = rot->count < num;
	bool 单例3 = scal->count < num;

	//S_多边形元素Array* 元素组 = nullptr;
	//switch (合并元素) {
	//	case 0: 元素组 = (S_多边形元素Array*)f_core_array_new(num, sizeof(S_多边形元素*), true); break;
	//	case 1: 元素组 = (S_多边形元素Array*)f_core_array_new(num + 1, sizeof(S_多边形元素*), true); break;
	//}
	//f_core_array_push_back((S_Array*)self->m_元素组, (uint8*)&元素);

	for (uint32 i = 0; i < num; ++i) {
		vec3 l;
		vec3 r;
		vec3 s;

		if(单例1) l = loc->ptr_userData[0];
		else l = loc->ptr_userData[i];

		if(单例2) r = rot->ptr_userData[0];
		else r = rot->ptr_userData[i];

		if(单例3) s = scal->ptr_userData[0];
		else s = scal->ptr_userData[i];

		S_多边形元素* face = f_surface_复制(self, 元素, l, r, s, 0);
		

		switch (合并元素) {
			case 0: 元素组->ptr_userData[i] = face; break;
			case 1: 元素组->ptr_userData[i+1] = face; break;
		}
		//f_core_array_push_back((S_Array*)self->m_元素组, (uint8*)face);
	}
	
	//return nullptr;
	return 元素组;
}

static S_多边形元素Array* f_多边形_四元数变换(S_多边形* self, S_多边形元素* 元素, const S_Vec4Array* loc) {
	uint32 num = DEF_Max(元素->count, loc->count);
	S_多边形元素Array* 元素组 = (S_多边形元素Array*)f_core_array_new(num, sizeof(S_多边形元素*), true);

	bool 单例1 = 元素->count < num;
	bool 单例2 = loc->count < num;

	for (uint32 i = 0; i < num; ++i) {
		S_多边形元素* face = f_surface_复制(self, 元素, {}, {}, {1,1,1}, 0);
		元素组->ptr_userData[i] = face;
	}

	for (uint32 i = 0; i < num; ++i) {
		auto* faceIndex = 元素组->ptr_userData[i]->ptr_userData;
		uint32 faceNum = 元素组->ptr_userData[i]->count;

		for (uint32 j = 0; j < faceNum; ++j) {
			auto* face = self->m_面.data();
			face[j]->vertIndex.data();
			face[j]->vertIndex.size();

		}
	}

	return 元素组;
}




void f_node_所有网格类节点JIT初始化() {
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_添加多边形顶点), "uvec2", "S_多边形*, S_Vec3Array*, S_Vec3Array*", f_surface_添加多边形顶点);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_添加多边形边), "S_边*", "S_多边形* self, uvec2 offset, int32 ", f_surface_添加多边形边);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_添加多边形纹理坐标), DEF_S(uvec2), "S_多边形*, S_Vec2Array*, const S_UI32Array*, S_uVec2Array*", f_surface_添加多边形纹理坐标);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_添加多边形元素), DEF_S(S_多边形元素*), "S_多边形*, S_Vec3Array*, S_UI32Array*, S_uVec2Array*", f_surface_添加多边形元素);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_从区间索引构建多边形面), "S_多边形元素*", "S_多边形* self, uvec2 index, uvec2, uint32, bool 反向", f_surface_从区间索引构建多边形面);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取面索引), "void", "S_多边形* self, S_多边形元素* 面元素, S_1DArray* 索引", f_surface_取面索引);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_投影纹理坐标), "void", "S_多边形* poly, int32 投影类型, S_多边形元素* 面元素, const Mat44f& mat", f_surface_投影纹理坐标);



	f_代码构建_添加JIT初始化函数指针(DEF_S(f_多边形_销毁边), "void", "S_边*", f_多边形_销毁边);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_多边形_边数量), "uint32", "S_边*", f_多边形_边数量);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_多边形_边_data), "uvec2*", "S_边*", f_多边形_边_data);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_多边形_复制), DEF_S(S_多边形元素Array*), "S_多边形* self, S_多边形元素*, const S_Vec3Array*, const S_Vec3Array*, const S_Vec3Array*, uint32, uint8", f_多边形_复制);
	
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_多边形_桥接), DEF_S(S_多边形元素*), "S_多边形* self, S_边* 边A, S_边* 边B", f_多边形_桥接);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_点桥接), DEF_S(S_Vec3Array*), "const S_Vec3Array*, const S_Vec3Array*, S_UI32Array*, S_uVec2Array*", f_surface_点桥接);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_多边形三角化), "void", "S_Mesh* mesh, const S_多边形* 多边形", f_surface_多边形三角化);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_边多点采样), "void", "S_边*, const vec2&, float32, float32, float32, float32, S_Vec3Array*, S_Vec3Array*", f_surface_边多点采样);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_边采样), "void", "S_边*, const vec2&, float32, S_Vec3Array*, S_Vec3Array*", f_surface_边采样);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_构建预设多边形), DEF_S(S_多边形元素*), "S_多边形* poly, const uvec3&, const vec3&, uint8", f_surface_构建预设多边形);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_线实体化), DEF_S(S_多边形元素Array*), "S_边Array*, S_Vec3Array*, S_F32Array*, const S_曲线&, int32, int32 ", f_surface_线实体化);
	//f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_销毁多边形元素), "void", "S_多边形元素* 面组", f_surface_销毁多边形元素);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_复制), DEF_S(S_多边形元素*), "S_多边形*, S_多边形元素*, const vec3&, const vec3&, const vec3&, uint8", f_surface_复制);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_拷贝多边形), DEF_S(S_多边形Array*), "const S_多边形Array*, S_多边形Array*, const S_Vec3Array*, const S_Vec3Array*, const S_Vec3Array*", f_surface_拷贝多边形);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_多边形变换), DEF_S(void), "S_多边形*, const vec3&, const vec3&, const vec3&", f_surface_多边形变换);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_多边形元素变换), DEF_S(void), "S_多边形元素*, const vec3&, const vec3&, const vec3&", f_surface_多边形元素变换);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_多边形元素组变换), DEF_S(void), "S_多边形元素Array*, const S_Vec3Array*, const S_Vec3Array*, const S_Vec3Array*", f_surface_多边形元素组变换);


	//f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_释放元素), DEF_S(void), "S_多边形*, S_多边形元素*", f_surface_释放元素);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_释放元素组), DEF_S(void), "S_多边形*, S_多边形元素Array*", f_surface_释放元素组);

	
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取面顶点), "void", "const S_面*, S_Vec3Array*", f_surface_取面顶点);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取面法线), "void", "const S_面*, S_Vec3Array*", f_surface_取面法线);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取面中心), "void", "const S_面*, S_Vec3Array*", f_surface_取面中心);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取面顶点法线), "void", "const S_面*, S_Vec3Array*", f_surface_取面顶点法线);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取多边形边), DEF_S(S_边*), "const S_多边形* self, uint32 ID", f_surface_取多边形边);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取多边形元素), DEF_S(S_多边形元素*), "S_多边形* self, uint32 元素索引", f_surface_取多边形元素);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取多边形多个元素), DEF_S(S_多边形元素Array*), "S_多边形* self, S_UI32Array* 元素索引", f_surface_取多边形多个元素);


	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_get网格顶点数据), DEF_S(void), "S_Mesh*, const S_UI32Array*, S_Vec3Array*, int32", f_surface_get网格顶点数据);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_set网格顶点数据), DEF_S(void), "S_Mesh*, const S_UI32Array*, const S_Vec3Array*, int32", f_surface_set网格顶点数据);

	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置面顶点), "void", "const S_面*, const S_Vec3Array*", f_surface_设置面顶点);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置面顶点法线), "void", "const S_面*, const S_Vec3Array*", f_surface_设置面顶点法线);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置面法线), "void", "const S_面*, const S_Vec3Array*", f_surface_设置面法线);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置面中心), "void", "S_多边形*, const S_面*, const S_Vec3Array*", f_surface_设置面中心);
	
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置元素UV环), "void", "S_多边形*, S_多边形元素*, S_uVec2Array*, uint32 uv层", f_surface_设置元素UV环);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置元素组UV环), "void", "S_多边形*, S_多边形元素Array*, S_uVec2Array*, uint32 uv层", f_surface_设置元素组UV环);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置元素材质槽ID), "void", "S_多边形*, const S_多边形元素*, S_UI32Array*", f_surface_设置元素材质槽ID);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置元素组材质槽ID), "void", "S_多边形*, const S_多边形元素Array*, S_UI32Array*", f_surface_设置元素组材质槽ID);



	//====================== 废弃 =============================
	//f_代码构建_添加JIT初始化函数指针(DEF_S(f_多边形_添加顶点节点cxx), "uvec2", "S_多边形* self, void* verts", f_多边形_添加顶点节点cxx);
}











C_计算网格法线节点::C_计算网格法线节点(S_设备环境& ctx) : C_节点基类("网格法线计算节点") {
	m_Ctx = ctx;
	m_Name = L"计算法线";
	m_Tree = nullptr;

	C_插座基类* socket;
	DEF_创建网格插座_I(L"网格");
	DEF_创建Vec3_1D插座_O(L"法线");

	m_法线类型 = f_alloc_EnumProp(nullptr, { {L"平滑", ""}, {L"平直", ""} }, L"平滑方式", 0);
	m_法线类型.m_私有 = true;
	m_执行代码 = f_alloc_BoolProp(nullptr, L"执行代码");
	m_执行代码.m_私有 = true;
}

C_计算网格法线节点::~C_计算网格法线节点() {
	f_prop_Release(m_法线类型);
	f_prop_Release(m_执行代码);
}

bool C_计算网格法线节点::f_update() {
	if (f_get输入插座(1)->m_有新数据 == false) return false;

	auto* inMesh = DEF_网格插座数据(f_get输入插座(1));
	if (f_get输入插座(1)->f_isLink() == false || !inMesh) {
		return false;
	}


	std::vector<vec3> vert;
	f_surface_get顶点坐标(inMesh, vert);
	std::vector<uvec3> index;
	f_surface_get顶点索引(inMesh, index);

	uint32 num = vert.size();
	auto* vert_p = vert.data();
	auto* index_p = index.data();

	auto normal = DEF_Vec3插座_1D数据(f_get输出插座(1));
	f_core_array_resize((S_Array*)normal, num);
	auto* normal_p = normal->ptr_userData;

	switch (f_prop_enum(m_法线类型)) {
	case 0: {
		if (!m_Tree) {
			float32 dimSize = DEF_Max(DEF_Max(inMesh->m_包围盒.size.x, inMesh->m_包围盒.size.y), inMesh->m_包围盒.size.z);
			assert(dimSize > 0);
			m_Tree = f_空间划分_create球形八叉树(dimSize);
		}

		std::vector<S_VecSphere> 包围盒;
		f_surface_计算三角形球体包围盒(inMesh, 包围盒);
		f_空间划分_从包围盒构建子集(m_Tree, 包围盒);
		

		for (uint32 i = 0; i < num; ++i) {
			std::vector<void*> 面索引_空间数据;
			f_空间划分_get位置子集数据(m_Tree, vert_p[i], 面索引_空间数据);

			vec3 法线 = {};
			for (auto e : 面索引_空间数据) {
				std::vector<uint32>& 面索引组 = *((std::vector<uint32>*)e);
				for (auto index : 面索引组) {
					uvec3 trangle = index_p[index];
					if (trangle.x == i || trangle.y == i || trangle.z == i) {
						法线 += f_surface_从面计算法线(vert_p[trangle.x], vert_p[trangle.y], vert_p[trangle.z]);
					}
				}
			}

			normal_p[i] = vec_normalize2(法线);
		}
		
		break;
	}

	case 1: {


		break;
	}

	}
	return false;
}

void C_计算网格法线节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_法线类型, f);
	f_prop_Load(m_执行代码, f);
}

void C_计算网格法线节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_法线类型, f);
	f_prop_Save(m_执行代码, f);
}

C_节点基类* f_node_创建计算网格法线节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_计算网格法线节点(ctx);
}

C_节点基类* f_node_载入计算网格法线节点(S_设备环境& ctx, FILE* f) {
	C_计算网格法线节点* node = new C_计算网格法线节点(ctx);
	//fread(&(((S_PropValueEnum*)node->m_计算方式.m_Value)->m_当前选项), sizeof(uint8), 1, f);
	return node;
}

void f_node_保存计算网格法线节点(C_节点基类* n, FILE* f) {
	C_计算网格法线节点* node = dynamic_cast<C_计算网格法线节点*>(n);
}









C_网格体素节点::C_网格体素节点(S_设备环境& ctx) : C_节点基类("网格体素节点") {
	m_Ctx = ctx;
	m_Name = L"网格体素";


	C_插座基类* socket;
	DEF_创建网格插座_I(L"网格");
	DEF_创建F32插座_v1_I(L"粒子大小");

	DEF_创建体素插座_O(L"体素");

	float32 粒子大小 = 0.1;
	f_get输入插座(2)->f_setData(&粒子大小);
}

C_网格体素节点::~C_网格体素节点() {
	S_体素* vo = DEF_体素插座数据(f_get输出插座(1));

	if (vo) {
		delete vo;
		f_get输出插座(1)->f_setData((void*)nullptr);
	}
}

bool C_网格体素节点::f_update() {
	S_体素* vo = DEF_体素插座数据(f_get输出插座(1));
	if (vo == nullptr) {
		vo = new S_体素();
		f_get输出插座(1)->f_setData(vo);
	}

	if (f_get输入插座(1)->m_Type != E_值类型::e_Type_Mesh) {
		vo->m_坐标.clear();
		vo->m_Mask.clear();
		vo->m_Index.clear();
		vo->m_法线.clear();
		vo->m_维度 = {};
		return false;
	}

	auto* inMesh = DEF_网格插座数据(f_get输入插座(1), 0);
	if (nullptr == inMesh) return false;

	auto 粒子大小 = DEF_F32插座数据(f_get输入插座(2));

	


	//auto mesh = f_surface_创建网格对象(inMesh.m_GPU网格, m_Ctx, E_网格数据枚举::e_Mesh_CUDA);
	f_fromMesh创建体素(*vo, inMesh, { 0,0,0 }, { 0,0,0 }, { 1,1,1 }, 粒子大小);
	//f_surface_释放网格对象(mesh);
	return false;
}



C_节点基类* f_node_创建网格体素节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_网格体素节点(ctx);
}

C_节点基类* f_node_载入网格体素节点(S_设备环境& ctx, FILE* f) {
	C_网格体素节点* node = new C_网格体素节点(ctx);
	return node;
}

void f_node_保存网格体素节点(C_节点基类* n, FILE* f) {
	C_网格体素节点* node = dynamic_cast<C_网格体素节点*>(n);
}



C_取网格属性节点::C_取网格属性节点(S_设备环境& ctx) : C_节点基类("网格属性节点") {
	m_Ctx = ctx;
	m_Name = L"取网格属性";


	C_插座基类* socket;
	DEF_创建网格插座_I(L"网格");

	DEF_创建Vec3_Array1D插座_O(L"属性");
	//DEF_创建Cube_1D插座_O(L"包围大小");

	m_网格属性 = f_alloc_EnumProp(nullptr, { {L"顶点", ""}, {L"法线", ""}, {L"UV", ""}, {L"面中心", ""}, {L"面法线", ""}, {L"索引", ""}, {L"包围盒", ""}}, L"属性");
	m_网格属性.m_私有 = true;
	m_执行代码 = f_alloc_BoolProp(nullptr, L"执行代码");
	m_执行代码.m_私有 = true;

}

C_取网格属性节点::~C_取网格属性节点() {

}

bool C_取网格属性节点::f_update() {
	auto* inMesh = DEF_网格插座数据(f_get输入插座(1), 0);
	//auto& out01_包围盒 = *DEF_Cube_1D插座数据(f_get输出插座(1));
	if (!inMesh) return false;

	switch (f_prop_enum(m_网格属性))
	{
	case 0: {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec3_Array1D);
		auto& outData = *DEF_Vec3_Array1D插座数据(f_get输出插座(1), 0);
		f_surface_get顶点坐标(inMesh, outData);
		break;
	}

	case 1: {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec3_Array1D);
		auto& outData = *DEF_Vec3_Array1D插座数据(f_get输出插座(1), 0);
		f_surface_get顶点法线(inMesh, outData);
		break;
	}

	case 2: {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec2_Array1D);
		auto& outData = *DEF_Vec2_Array1D插座数据(f_get输出插座(1), 0);
		f_surface_get纹理坐标(inMesh, outData);
		break;
	}

	case 3: {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec3_Array1D);
		auto& outData = *DEF_Vec3_Array1D插座数据(f_get输出插座(1), 0);
		f_surface_计算面中心点(inMesh, outData);
		break;
	}

	case 4: {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec3_Array1D);
		auto& outData = *DEF_Vec3_Array1D插座数据(f_get输出插座(1), 0);
		f_surface_计算面法线(inMesh, outData);
		break;
	}

	default:
		break;
	}
	//out01_包围盒.resize(num);
	//for (uint32 i = 0; i < num; ++i) {
	//	S_Bounding cube = f_surface_计算包围盒(p_mesh[i]);
	//	out01_包围盒[i].size = vec_sub(cube.max, cube.min);
	//	out01_包围盒[i].pos = vec_add(cube.min, vec_multi(out01_包围盒[i].size, 0.5f));
	//}
	return false;
}

void C_取网格属性节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_网格属性, f);
	f_prop_Load(m_执行代码, f);
}

void C_取网格属性节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_网格属性, f);
	f_prop_Save(m_执行代码, f);
}

C_节点基类* f_node_创建取网格属性节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取网格属性节点(ctx);
}

C_节点基类* f_node_载入取网格属性节点(S_设备环境& ctx, FILE* f) {
	C_取网格属性节点* node = new C_取网格属性节点(ctx);
	return node;
}

void f_node_保存取网格属性节点(C_节点基类* n, FILE* f) {
	C_取网格属性节点* node = dynamic_cast<C_取网格属性节点*>(n);
}







C_截取网格节点::C_截取网格节点(S_设备环境& ctx): C_节点基类("截取网格节点") {
	m_Ctx = ctx;
	m_Name = L"截取网格";
	m_Tree = nullptr;

	C_插座基类* socket;
	DEF_创建网格插座_I(L"网格");
	DEF_创建引用插座_I(L"查找索引");

	DEF_创建网格插座_O(L"新网格");

	m_截取方式 = f_alloc_EnumProp(nullptr, { {L"点", ""}, {L"线", ""}, {L"面", ""}, {L"元素", ""} }, L"截取类型", 2);
	m_截取方式.m_私有 = true;
	m_执行代码 = f_alloc_BoolProp(nullptr, L"执行代码");
	m_执行代码.m_私有 = true;

	m_Mesh = f_surface_创建网格对象(nullptr, m_Ctx, E_网格数据枚举::e_Mesh_VULKAN);
	f_get输出插座(1)->f_setData(m_Mesh);
}

C_截取网格节点::~C_截取网格节点() {
	f_prop_Release(m_截取方式);
	f_prop_Release(m_执行代码);

	f_surface_释放网格(m_Mesh);
}

bool C_截取网格节点::f_update() {
	auto& inData2 = *DEF_引用插座数据(f_get输入插座(2), 0);


	if (f_get输入插座(1)->f_isLink() && f_get输入插座(2)->f_isLink()) {
		auto* inMesh = DEF_网格插座数据(f_get输入插座(1), 0);

		if (!m_Tree) {
			float32 dimSize = DEF_Max(DEF_Max(inMesh->m_包围盒.size.x, inMesh->m_包围盒.size.y), inMesh->m_包围盒.size.z);
			m_Tree = f_空间划分_create球形八叉树(dimSize);
		}

		if (f_get输入插座(1)->m_有新数据) {
			std::vector<S_VecSphere> 包围盒;
			f_surface_计算三角形球体包围盒(inMesh, 包围盒);
			f_空间划分_从包围盒构建子集(m_Tree, 包围盒);
		}
		



		std::vector<vec3> vert;
		f_surface_get顶点坐标(inMesh, vert);
		std::vector<uvec3> index;
		f_surface_get顶点索引(inMesh, index);

		std::vector<vec3> 新顶点;
		std::vector<uvec3> 新顶点索引;
		std::map<uint32, uint32> 重新映射索引;
		uint32 indexOffset = 0;

		switch (inData2.m_Type)
		{
		case E_值类型::e_Type_Vec3: {
			vec3 coord = *DEF_引用转Vec3(inData2);
			std::vector<void*> index_空间数据;
			f_空间划分_get位置子集数据(m_Tree, coord, index_空间数据);

			for (auto e : index_空间数据) {
				std::vector<uint32>& indexs = *((std::vector<uint32>*)e);
				for (auto i : indexs) {
					std::cout << "i = " << i << std::endl;
					uvec3 trangle = index[i];
					uvec3 new_index;

					
					if (重新映射索引.find(trangle.x) != 重新映射索引.end()) {
						new_index.x = 重新映射索引[trangle.x];
					}
					else {
						重新映射索引[trangle.x] = indexOffset;
						new_index.x = indexOffset;
						新顶点.push_back(vert[trangle.x]);
						++indexOffset;
					}

					if (重新映射索引.find(trangle.y) != 重新映射索引.end()) {
						new_index.y = 重新映射索引[trangle.y];
					}
					else {
						重新映射索引[trangle.y] = indexOffset;
						new_index.y = indexOffset;
						新顶点.push_back(vert[trangle.y]);
						++indexOffset;
					}

					if (重新映射索引.find(trangle.z) != 重新映射索引.end()) {
						new_index.z = 重新映射索引[trangle.z];
					}
					else {
						重新映射索引[trangle.z] = indexOffset;
						new_index.z = indexOffset;
						新顶点.push_back(vert[trangle.z]);
						++indexOffset;
					}

					新顶点索引.push_back(new_index);
				}
			}

			
			f_surface_fill顶点数据(m_Mesh, 新顶点);
			f_surface_fill索引数据(m_Mesh, 新顶点索引);
			break;
		}
		case E_值类型::e_Type_Vec3_Array1D: {
			std::vector<void*> index_空间数据;
			f_空间划分_get位置子集数据(m_Tree, {}, index_空间数据);

			for (auto e : index_空间数据) {
				std::vector<uint32>& indexs = *((std::vector<uint32>*)e);
				for (auto i : indexs) {
					std::cout << "i = " << i << std::endl;
				}
			}
			break;
		}
		case E_值类型::e_插座Type_八叉树: {

			break;
		}
		default:
			break;
		}

	}
	else {
		f_surface_清空顶点数据(m_Mesh);
		f_surface_清空索引数据(m_Mesh);
	}

	return false;
}

void C_截取网格节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_截取方式, f);
	f_prop_Load(m_执行代码, f);
}

void C_截取网格节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_截取方式, f);
	f_prop_Save(m_执行代码, f);
}

C_节点基类* f_node_创建截取网格节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_截取网格节点(ctx);
}

C_节点基类* f_node_载入截取网格节点(S_设备环境& ctx, FILE* f) {
	C_截取网格节点* node = new C_截取网格节点(ctx);
	return node;
}

void f_node_保存截取网格节点(C_节点基类* n, FILE* f) {
	C_截取网格节点* node = dynamic_cast<C_截取网格节点*>(n);
}





C_填充网格顶点节点::C_填充网格顶点节点(S_设备环境& ctx): C_节点基类(DEF_填充网格顶点节点) {
	m_Ctx = ctx;
	m_Name = L"填充网格顶点";

	C_插座基类* socket;
	DEF_创建网格插座_I(L"网格");
	DEF_创建Vec3_1D插座_I(L"坐标");
	//DEF_创建UI32_1D插座_I(L"索引");

	DEF_创建网格插座_O(L"网格");
	

	m_网格属性 = f_alloc_EnumProp(nullptr, { {L"顶点", ""}, {L"法线", ""} }, L"元素类型", 2);
	m_网格属性.m_私有 = true;
}

C_填充网格顶点节点::~C_填充网格顶点节点() {
	f_prop_Release(m_网格属性);
}

bool C_填充网格顶点节点::f_update() {
	auto* inMesh = DEF_网格插座数据(f_get输入插座(1), 0);

	if (inMesh) {
		auto* socket2 = f_get输入插座(2);
		auto& 顶点 = *DEF_Vec3插座_1D数据(socket2);

		switch (f_prop_enum(m_网格属性)) {
		case 0: {
			if(socket2->f_get接入的数据类型())
			f_surface_fill顶点数据(inMesh, 顶点.ptr_userData, 顶点.count);
			break;
		}

		case 1: {
			f_surface_fill法线数据(inMesh, 顶点.ptr_userData, 顶点.count);
			break;
		}
		}
	}
	
	f_get输出插座(1)->f_setData(inMesh);

	return false;
}

void C_填充网格顶点节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_网格属性, f);
}

void C_填充网格顶点节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_网格属性, f);
}

C_节点基类* f_node_创建填充网格顶点节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_填充网格顶点节点(ctx);
}

C_节点基类* f_node_载入填充网格顶点节点(S_设备环境& ctx, FILE* f) {
	C_填充网格顶点节点* node = new C_填充网格顶点节点(ctx);
	return node;
}

void f_node_保存填充网格顶点节点(C_节点基类* n, FILE* f) {
	C_填充网格顶点节点* node = dynamic_cast<C_填充网格顶点节点*>(n);
}






C_填充网格纹理坐标节点::C_填充网格纹理坐标节点(S_设备环境& ctx): C_节点基类(DEF_填充网格纹理坐标节点) {
	m_Ctx = ctx;
	m_Name = L"填充纹理坐标";

	C_插座基类* socket;
	DEF_创建网格插座_I(L"网格");
	DEF_创建Vec2_1D插座_I(L"坐标");
	DEF_创建UI32插座_I(L"层");

	DEF_创建网格插座_O(L"网格");

}

C_填充网格纹理坐标节点::~C_填充网格纹理坐标节点() {
	
}

bool C_填充网格纹理坐标节点::f_update() {
	auto* inMesh = DEF_网格插座数据(f_get输入插座(1), 0);

	if (inMesh) {
		auto* socket2 = f_get输入插座(2);
		auto& 坐标 = *DEF_Vec2插座_1D数据(socket2);
		f_surface_fill纹理坐标(inMesh, 坐标.ptr_userData, 坐标.count);
	}

	f_get输入插座(1)->f_setData(inMesh);

	return false;
}

void C_填充网格纹理坐标节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_填充网格纹理坐标节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

C_节点基类* f_node_创建填充网格纹理坐标节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_填充网格纹理坐标节点(ctx);
}

C_节点基类* f_node_载入填充网格纹理坐标节点(S_设备环境& ctx, FILE* f) {
	C_填充网格纹理坐标节点* node = new C_填充网格纹理坐标节点(ctx);
	return node;
}

void f_node_保存填充网格纹理坐标节点(C_节点基类* n, FILE* f) {
	C_填充网格纹理坐标节点* node = dynamic_cast<C_填充网格纹理坐标节点*>(n);
}



C_面朝向节点::C_面朝向节点(S_设备环境& ctx) : C_节点基类(DEF_面朝向节点, E_节点类型::e_节点Type_网格) {
	m_Ctx = ctx;
	m_Name = L"面朝向";

	C_插座基类* socket;
	DEF_创建网格插座_I(L"网格");
	DEF_创建Bool_1D插座_I(L"反转");

	DEF_创建网格插座_O(L"网格");
}

C_面朝向节点::~C_面朝向节点() {
}

bool C_面朝向节点::f_update() {
	auto* socket1 = f_get输入插座(1);
	if (socket1->f_isLink()) {
		switch (socket1->f_get接入的数据类型()) {
		case E_值类型::e_Type_Object: f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Mesh); break;
		case E_值类型::e_Type_Object_1D: f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_Mesh_1D); break;
		default:
			break;
		}
		socket1 = f_get输入插座(1);

		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, socket1->m_Type);


		switch (socket1->m_Type) {
		case E_值类型::e_Type_多边形: {
			break;
		}
		case E_值类型::e_Type_Mesh: {
			auto* mesh = DEF_网格插座数据(socket1);
			f_surface_get顶点索引(mesh, m_顶点索引);

			uint32 num = m_顶点索引.size() / 3;
			std::vector<uvec3> 新顶点索引(num);
			auto* face_ptr = 新顶点索引.data();
			auto* index_ptr = (uvec3*)m_顶点索引.data();
			
			for (uint32 i = 0; i < num; ++i) {
				face_ptr[i].x = index_ptr[i].z;
				face_ptr[i].y = index_ptr[i].y;
				face_ptr[i].z = index_ptr[i].x;
			}
			break;
		}
		default:
			break;
		}


	}
	else {

		switch (socket1->m_Type) {
		case E_物体类型::t_多边形: {
			break;
		}
		case E_物体类型::t_网格: {
			auto* mesh = DEF_网格插座数据(socket1);
			if (mesh) {
				f_surface_fill索引数据(mesh, m_顶点索引);
			}
			break;
		}
		default:
			break;
		}

	}

	return false;
}

C_节点基类* f_node_创建面朝向节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_面朝向节点(ctx);
}
C_节点基类* f_node_载入面朝向节点(S_设备环境& ctx, FILE* f) {
	C_面朝向节点* node = new C_面朝向节点(ctx);
	return node;
}
void		f_node_保存面朝向节点(C_节点基类* n, FILE* f) {
	C_面朝向节点* node = dynamic_cast<C_面朝向节点*>(n);
}






C_设置材质ID节点::C_设置材质ID节点(S_设备环境& ctx) : C_节点基类(DEF_设置材质节点, E_节点类型::e_节点Type_网格) {
	m_Ctx = ctx;
	m_Name = L"设置材质";
	
	C_插座基类* socket;
	DEF_创建网格插座_I(L"网格");
	DEF_创建材质插座_I(L"材质");
	DEF_创建UI32_1D插座_I(L"面");
	
	DEF_创建网格插座_O(L"网格");

	m_以前的材质 = nullptr;
}

C_设置材质ID节点::~C_设置材质ID节点() {

}

bool C_设置材质ID节点::f_update() {
	if (f_get输入插座(1)->m_有新数据 || f_get输入插座(2)->m_有新数据 || f_get输入插座(3)->m_有新数据) {
		auto* 网格 = DEF_网格插座数据(f_get输入插座(1), 0);
		if (网格) {
			if (f_get输入插座(2)->f_isLink()) {

				auto* 材质 = DEF_材质插座数据(f_get输入插座(2), 0);
				auto& id = *DEF_UI32插座_1D数据(f_get输入插座(3));
				//uint64* matPtr = f_buf_map板载缓存<uint64>(网格->m_材质ID);
				if (m_以前的材质) {
					网格->m_光追材质链接.erase(m_以前的材质);
				}
				if (f_get输入插座(1)->f_isLink()) {
					uint32* id_ptr = id.ptr_userData;
				}
				else {
				}
				f_get输出插座(1)->f_setData(网格);
			}
			else {
				网格->m_光追材质链接.erase(m_以前的材质);
				f_get输出插座(1)->f_setData((void*)nullptr);
			}
		}
		else {
			网格 = DEF_网格插座数据(f_get输出插座(1), 0);
			if (网格 && m_以前的材质) {
				网格->m_光追材质链接.erase(m_以前的材质);
			}
		}
	}
	
	return false;
}

void C_设置材质ID节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_设置材质ID节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

C_节点基类* f_node_创建设置材质ID节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_设置材质ID节点(ctx);
}

C_节点基类* f_node_载入设置材质ID节点(S_设备环境& ctx, FILE* f) {
	C_设置材质ID节点* node = new C_设置材质ID节点(ctx);
	return node;
}

void f_node_保存设置材质ID节点(C_节点基类* n, FILE* f) {
	C_设置材质ID节点* node = dynamic_cast<C_设置材质ID节点*>(n);
}




C_设置网格属性节点::C_设置网格属性节点(S_设备环境& ctx) : C_节点基类(DEF_设置网格属性节点, E_节点类型::e_节点Type_网格) {
	m_Ctx = ctx;
	m_Name = L"设置网格属性";
	m_子集节点树 = nullptr;

	C_插座基类* socket;
	DEF_创建网格_1D插座_I(L"网格");
	DEF_创建引用插座_I(L"属性");
	DEF_创建UI32插座_I(L"通道");

	DEF_创建引用插座_O(L"网格");
}

C_设置网格属性节点::~C_设置网格属性节点() {

}

bool C_设置网格属性节点::f_update() {
	return false;
}

void C_设置网格属性节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_设置网格属性节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

C_节点基类* f_node_创建设置网格属性节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_设置网格属性节点(ctx);
}

C_节点基类* f_node_载入设置网格属性节点(S_设备环境& ctx, FILE* f) {
	C_设置网格属性节点* node = new C_设置网格属性节点(ctx);
	return node;
}

void f_node_保存设置网格属性节点(C_节点基类* n, FILE* f) {
	C_设置网格属性节点* node = dynamic_cast<C_设置网格属性节点*>(n);
}






C_多边形删除顶点节点::C_多边形删除顶点节点(S_设备环境& ctx) : C_节点基类(DEF_多边形删除顶点节点, E_节点类型::e_节点Type_多边形) {
	m_Ob = nullptr;
}

C_多边形删除顶点节点::~C_多边形删除顶点节点() {
}

bool C_多边形删除顶点节点::f_update() {

	return false;
}

S_物体* C_多边形删除顶点节点::f_get虚拟体() {
	return m_Ob;
}

void C_多边形删除顶点节点::f_入回收() {
	assert(m_Ob);
	f_NodeCtx_get默认场景()->f_remove物体(m_Ob, E_场景物体容器类型::e_集合);
}

void C_多边形删除顶点节点::f_回收() {
	f_NodeCtx_get默认场景()->f_add物体({ m_Ob }, E_场景物体容器类型::e_集合);
}

C_节点基类* f_node_创建多边形删除顶点节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形删除顶点节点(ctx);
}

C_节点基类* f_node_载入多边形删除顶点节点(S_设备环境& ctx, FILE* f) {
	C_多边形删除顶点节点* node = new C_多边形删除顶点节点(ctx);
	return node;
}

void f_node_保存多边形删除顶点节点(C_节点基类* n, FILE* f) {
	C_多边形删除顶点节点* node = dynamic_cast<C_多边形删除顶点节点*>(n);
}




C_构建多边形面节点::C_构建多边形面节点(S_设备环境& ctx) : C_节点基类(DEF_多边形面节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"面";
	m_Ctx = ctx;
	
	C_插座基类* socket;
	DEF_创建uVec2插座_I(L"索引");
	DEF_创建uVec2插座_I(L"UV");
	DEF_创建UI32插座_I(L"层");

	DEF_创建多边形元素插座_O(L"面");

	//m_Ob = f_node_网格节点创建物体数据(ctx);
	m_Ob = nullptr;

	m_面朝向 = f_alloc_BoolProp(nullptr, L"面朝向");
	m_面朝向.m_私有 = true;

}

C_构建多边形面节点::~C_构建多边形面节点() {
}

bool C_构建多边形面节点::f_update() {
	auto& 索引 = DEF_uVec2插座数据(f_get输入插座(1));

	auto* 面 = DEF_多边形面插座数据(f_get输出插座(1), 0);
	if (!面) {
		f_get输出插座(1)->f_setData(面);
	}
	return false;
}

S_物体* C_构建多边形面节点::f_get虚拟体() {
	return m_Ob;
}

std::string	C_构建多边形面节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";

	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);
	
	m_Code = DEF_S(S_多边形元素*)" " + name + ";\n";
	m_Code += "{\n";

	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);

	C_节点树* t = f_getThis节点树();
	auto 反向 = f_代码构建_属性变量(m_面朝向, t);

	//m_Code += "uvec2 indexRange = " + socket1->f_getCode() + ";\n";
	m_Code += name + " = " + DEF_S(f_surface_从区间索引构建多边形面) + "(g多边形, " + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ", " + 反向 + ");\n";
	
	m_Code += m_ReleaseCode;
	m_Code += "}\n";


	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_构建多边形面节点::f_入回收() {
	if (m_Ob) {
		f_NodeCtx_get默认场景()->f_remove物体(m_Ob, E_场景物体容器类型::e_集合);
	}
}

void C_构建多边形面节点::f_回收() {
	f_NodeCtx_get默认场景()->f_add物体({ m_Ob }, E_场景物体容器类型::e_集合);
}

void C_构建多边形面节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_构建多边形面节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

C_节点基类* f_node_创建构建多边形面节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_构建多边形面节点(ctx);
}

C_节点基类* f_node_载入构建多边形面节点(S_设备环境& ctx, FILE* f) {
	C_构建多边形面节点* node = new C_构建多边形面节点(ctx);
	return node;
}

void f_node_保存构建多边形面节点(C_节点基类* n, FILE* f) {
	C_构建多边形面节点* node = dynamic_cast<C_构建多边形面节点*>(n);
}




C_边倒角::C_边倒角(S_设备环境& ctx) : C_节点基类(DEF_线倒角节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"边";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建曲线采样值_1D插座_I(L"半径", nullptr);
	DEF_创建F32插座_I(L"细分", nullptr);
	DEF_创建多边形边插座_I(L"边");
	

	DEF_创建多边形插座_O(L"多边形");

	m_细分类型 = f_alloc_EnumProp(nullptr, { {L"距离", ""}, {L"数量", ""} }, L"细分类型", 0);
	m_细分类型.m_私有 = true;

}

C_边倒角::~C_边倒角() {
}

bool C_边倒角::f_update() {

	S_2D曲线数值* curve = DEF_曲线采样值插座数据(f_get输入插座(1), 0);


	switch (f_prop_enum(m_细分类型))
	{
	case 0: {

		break;
	}

	case 1: {

		break;
	}
	}

	//f_graph_采样曲线值(curve);

	return false;
}

C_节点基类* f_node_创建多边形倒角节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_边倒角(ctx);
}

C_节点基类* f_node_载入多边形倒角节点(S_设备环境& ctx, FILE* f) {
	C_边倒角* node = new C_边倒角(ctx);
	return node;
}

void f_node_保存多边形倒角节点(C_节点基类* n, FILE* f) {

}




C_多边形桥接::C_多边形桥接(S_设备环境& ctx) : C_节点基类(DEF_多边形桥接节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"桥接";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形边插座_I(L"边A");
	DEF_创建多边形边插座_I(L"边B");

	DEF_创建多边形元素插座_O(L"面");

	m_Ob = f_node_网格节点创建物体数据(ctx);
}

C_多边形桥接::~C_多边形桥接() {
}

bool C_多边形桥接::f_update() {
	return false;
}

std::string C_多边形桥接::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	m_Code = DEF_S(S_多边形元素*)" " + name + ";\n";

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);

	m_Code += name + " = " DEF_S(f_多边形_桥接);
	m_Code += "(g多边形, ";
	m_Code += socket1->f_getCode(0) + ", " + socket2->f_getCode(0);
	m_Code += ");\n ";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";


	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}

	return m_Code;
}

C_节点基类* f_node_创建多边形桥接节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形桥接(ctx);
}

C_节点基类* f_node_载入多边形桥接节点(S_设备环境& ctx, FILE* f) {
	C_多边形桥接* node = new C_多边形桥接(ctx);
	return node;
}

void f_node_保存多边形桥接节点(C_节点基类* n, FILE* f) {
	C_多边形桥接* node = dynamic_cast<C_多边形桥接*>(n);
}




C_点桥接::C_点桥接(S_设备环境& ctx) : C_节点基类(DEF_点桥接节点, E_节点类型::e_节点Type_多边形) {
	m_Name = L"桥接";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建Vec3_1D插座_I(L"点A");
	DEF_创建Vec3_1D插座_I(L"点B");

	DEF_创建Vec3_1D插座_O(L"点");
	DEF_创建UI32_1D插座_O(L"索引");
	DEF_创建uVec2_1D插座_O(L"环");
}

C_点桥接::~C_点桥接() {
}

bool C_点桥接::f_update() {
	return false;
}

std::string C_点桥接::DEF_节点编译函数 {
	m_Code = "";
	m_ReleaseCode = "";
	

	auto* outSocket1 = f_get输出插座(1);
	auto* outSocket2 = f_get输出插座(2);
	auto* outSocket3 = f_get输出插座(3);
	std::string name1 = f_getName() + outSocket1->f_getName();
	std::string name2 = f_getName() + outSocket2->f_getName();
	std::string name3 = f_getName() + outSocket3->f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	m_Code += DEF_S(S_Vec3Array*)" " + name1 + ";\n";
	m_Code += DEF_S(S_UI32Array*)" " + name2 + ";\n";
	m_Code += DEF_S(S_uVec2Array*)" " + name3 + ";\n";

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);

	//m_Code += name1 + " = (S_Vec3Array*)" + DEF_S(f_core_array_from)"((S_Array*)" + socket1->f_getCode() + ");\n";
	//m_Code += DEF_S(f_core_array_append)"((S_Array*)" + name1 + ", (S_Array*)" + socket2->f_getCode() + ");\n";
	//m_Code += name1 + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec3_1D, "1") + ";\n";
	m_Code += name2 + " = " + f_代码构建_创建Array(E_值类型::e_Type_UI32_1D, "1") + ";\n";
	m_Code += name3 + " = " + f_代码构建_创建Array(E_值类型::e_Type_uVec2_1D, "1") + ";\n";

	m_Code += name1 + " = " + DEF_S(f_surface_点桥接);
	m_Code += "(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + name2 + ", " + name3 + ");\n ";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";


	f_get输出插座(1)->f_setCode(name1);
	f_get输出插座(2)->f_setCode(name2);
	f_get输出插座(3)->f_setCode(name3);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name1);
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name2);
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name3);
		return "";
	}
	释放 += f_代码构建_销毁数组(name1);
	释放 += f_代码构建_销毁数组(name2);
	释放 += f_代码构建_销毁数组(name3);
	return m_Code;
}

void C_点桥接::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_点桥接::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

C_节点基类* f_node_创建点桥接节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_点桥接(ctx);
}
C_节点基类* f_node_载入点桥接节点(S_设备环境& ctx, FILE* f) {
	C_点桥接* node = new C_点桥接(ctx);
	return node;
}
void		f_node_保存点桥接节点(C_节点基类* n, FILE* f) {
	C_点桥接* node = dynamic_cast<C_点桥接*>(n);
}




C_多边形边网格化::C_多边形边网格化(S_设备环境& ctx) : C_节点基类(DEF_多边形边网格化节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"网格化";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形边插座_I(L"边");
	DEF_创建多边形边插座_I(L"倒角");

}

C_多边形边网格化::~C_多边形边网格化() {
}

bool C_多边形边网格化::f_update() {
	return false;
}

std::string C_多边形边网格化::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	m_Code = "{\n";

	auto 边 = f_get输入插座(1)->f_构建变量代码(0);
	auto 倒角 = f_get输入插座(2)->f_构建变量代码(0);

	m_Code += m_ReleaseCode;
	m_Code += "}\n";
	return m_Code;
}

C_节点基类* f_node_创建多边形边网格化节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形边网格化(ctx);
}
C_节点基类* f_node_载入多边形边网格化节点(S_设备环境& ctx, FILE* f) {
	C_多边形边网格化* node = new C_多边形边网格化(ctx);
	return node;
}
void f_node_保存多边形边网格化节点(C_节点基类* n, FILE* f) {
	C_多边形边网格化* node = dynamic_cast<C_多边形边网格化*>(n);
}





C_多边形边采样::C_多边形边采样(S_设备环境& ctx) : C_节点基类(DEF_多边形边采样节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"边采样";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形边插座_I(L"边");
	DEF_创建Vec2插座_I(L"区间");
	DEF_创建F32插座_I(L"偏移", nullptr);

	DEF_创建F32插座_I(L"间隔", nullptr);
	DEF_创建F32插座_I(L"随机间隔", nullptr);
	DEF_创建F32插座_I(L"随机种子", nullptr);
	

	DEF_创建Vec3_1D插座_O(L"坐标点");
	DEF_创建Vec3_1D插座_O(L"坐标向量");


	DEF_Vec2插座数据(f_get输入插座(2), 0) = { 0, 1 };
	DEF_F32插座数据(f_get输入插座(3)) = 0.1;
	DEF_F32插座数据(f_get输入插座(4)) = 0.1;
	DEF_F32插座数据(f_get输入插座(5)) = 0;


	m_多点采样 = f_alloc_BoolProp(nullptr, L"多点采样");
	m_多点采样.m_私有 = true;
	f_prop_Bool(m_多点采样) = true;

}

C_多边形边采样::~C_多边形边采样() {
	f_prop_Release(m_多点采样);
}

bool C_多边形边采样::f_update() {
	auto* socket1 = f_get输入插座(1);

	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);
	auto* socket4 = f_get输入插座(4);
	auto* socket5 = f_get输入插座(5);
	auto* socket6 = f_get输入插座(6);

	S_边* 边 = DEF_多边形边插座数据(socket1);
	vec2 采样区间 = DEF_Vec2插座数据(socket2);
	float32 偏移 = DEF_F32插座数据(socket3);

	float32 最小间隔 = DEF_F32插座数据(socket4);
	float32 随机间隔 = DEF_F32插座数据(socket5);
	float32 随机种子 = DEF_F32插座数据(socket6);
	

	if (f_prop_Bool(m_多点采样)) {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec3_1D);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 2, E_值类型::e_Type_Vec3_1D);

		S_Vec3Array* 采样的坐标 = DEF_Vec3插座_1D数据(f_get输出插座(1));
		S_Vec3Array* 采样的法线 = DEF_Vec3插座_1D数据(f_get输出插座(2));

		f_surface_边多点采样(边, 采样区间, 最小间隔, 随机间隔, 随机种子, 偏移, 采样的坐标, 采样的法线);
	}
	else {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec3);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 2, E_值类型::e_Type_Vec3);

		vec3& 采样的坐标 = DEF_Vec3插座数据(f_get输出插座(1));
		vec3& 采样的法线 = DEF_Vec3插座数据(f_get输出插座(2));

		f_surface_边采样(边, 采样区间, 偏移, 采样的坐标, 采样的法线);
	}
	
	return false;
}

std::string C_多边形边采样::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	m_Code = "";
	m_ReleaseCode = "";

	std::string name = f_getName();

	std::string 坐标点 = "坐标点_"+name;
	std::string 坐标向量 = "坐标向量_"+name;

	m_Code = f_代码构建_创建vec3_Array(坐标点, "0");
	m_Code += f_代码构建_创建vec3_Array(坐标向量, "0");


	auto* socket1 = f_get输入插座(1);
	

	if (socket1->f_isLink()) {
		auto* socket2 = f_get输入插座(2);
		auto* socket3 = f_get输入插座(3);
		auto* socket4 = f_get输入插座(4);
		auto* socket5 = f_get输入插座(5);
		auto* socket6 = f_get输入插座(6);


		m_Code += "{\n";
		m_Code += socket1->f_构建变量代码(0);
		m_Code += socket2->f_构建变量代码(0);
		m_Code += socket3->f_构建变量代码(0);
		m_Code += socket4->f_构建变量代码(0);
		m_Code += socket5->f_构建变量代码(0);
		m_Code += socket6->f_构建变量代码(0);

		if (f_prop_Bool(m_多点采样)) {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec3_1D);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 2, E_值类型::e_Type_Vec3_1D);

			m_Code += DEF_S(f_surface_边多点采样);
			m_Code += "(";
			m_Code += socket1->f_getCode(0) + ", ";
			m_Code += socket2->f_getCode(0) + ", ";
			m_Code += socket3->f_getCode(0) + ", ";
			m_Code += socket4->f_getCode(0) + ", ";
			m_Code += socket5->f_getCode(0) + ", ";
			m_Code += socket6->f_getCode(0) + ", ";

			m_Code += 坐标点 + ", ";
			m_Code += 坐标向量 + ");\n";
		}
		else {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_Vec3);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 2, E_值类型::e_Type_Vec3);


			m_Code += DEF_S(f_surface_边采样);
			m_Code += "(";
			m_Code += socket1->f_getCode(0) + ", ";
			m_Code += socket2->f_getCode(0) + ", ";
			m_Code += socket3->f_getCode(0) + ", ";

			m_Code += 坐标点 + ", ";
			m_Code += 坐标向量 + ");\n";
		}
		


		m_Code += m_ReleaseCode;
		m_Code += "}\n";

		f_get输出插座(1)->f_setCode(坐标点);
		f_get输出插座(2)->f_setCode(坐标向量);
	}
	

	

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(坐标点);
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(坐标向量);
		return "";
	}

	释放 += f_代码构建_销毁数组(坐标点);
	释放 += f_代码构建_销毁数组(坐标向量);
	return m_Code;
}

void C_多边形边采样::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		下一次读取数据指针 = f_prop_Load(m_多点采样, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_多边形边采样::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_多点采样, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);

	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建多边形边采样节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形边采样(ctx);
}

C_节点基类* f_node_载入多边形边采样节点(S_设备环境& ctx, FILE* f) {
	C_多边形边采样* node = new C_多边形边采样(ctx);
	return node;
}

void f_node_保存多边形边采样节点(C_节点基类* n, FILE* f) {
	C_多边形边采样* node = dynamic_cast<C_多边形边采样*>(n);
}




C_多边形边实体化::C_多边形边实体化(S_设备环境& ctx) : C_节点基类(DEF_多边形边实体化节点) {
	m_Ctx = ctx;
	m_Name = L"边实体化";

	C_插座基类* socket;
	DEF_创建多边形边_1D插座_I(L"值");
	DEF_创建Vec3_1D插座_I(L"边点");
	DEF_创建F32_1D插座_I(L"半径");

	DEF_创建多边形元素_1D插座_O(L"多边形");



	m_倒角类型 = f_alloc_EnumProp(nullptr, {
		{L"节点", ""},
		{L"采样", ""},
							  }, L"选择类型", 0);
	m_倒角类型.m_私有 = true;

	m_半径模式 = f_alloc_EnumProp(nullptr, {
		{L"独立", ""},
		{L"采样", ""},
	}, L"倒角类型", 0);
	m_半径模式.m_私有 = true;

	m_曲线 = f_alloc_2DCurveProp(nullptr, L"曲线");
	m_曲线.m_私有 = true;

}

C_多边形边实体化::~C_多边形边实体化() {
	f_prop_Release(m_倒角类型);
	f_prop_Release(m_半径模式);
	f_prop_Release(m_曲线);
}

bool C_多边形边实体化::f_update() {
	return false;
}

std::string C_多边形边实体化::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	m_Code = "";
	m_ReleaseCode = "";

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	std::string name = f_getName();
	m_Code += DEF_S(S_多边形元素Array*)" " + name + ";\n";

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);

	auto* rt = f_getThis节点树();
	auto 倒角 = f_代码构建_属性变量(m_倒角类型, rt);
	auto 半径 = f_代码构建_属性变量(m_半径模式, rt);
	auto 曲线 = f_代码构建_属性变量(m_曲线, rt);

	m_Code += name + " = ";
	m_Code += DEF_S(f_surface_线实体化)"("; 
	m_Code += socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ", " + 曲线 + ", " + 倒角 + ", " + 半径 + ");\n";

	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_多边形边实体化::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		if (f_file_版本对比(文件块, S_节点数据::g_低版本号_5, S_节点数据::g_文件版本号)) {
			const uint8* 下一次读取数据指针 = 文件块.m_data;
			下一次读取数据指针 = f_prop_Load(m_倒角类型, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_半径模式, 下一次读取数据指针);

			下一次读取数据指针 = f_prop_Load(m_曲线, 下一次读取数据指针);
		}
		else if (f_file_版本对比(文件块, S_节点数据::g_低版本号_0, S_节点数据::g_文件版本号)) {
			const uint8* 下一次读取数据指针 = 文件块.m_data;
			下一次读取数据指针 = f_prop_Load(m_倒角类型, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_半径模式, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_多边形边实体化::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_倒角类型, 块);
	f_prop_Save(m_半径模式, 块);
	f_prop_Save(m_曲线, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建多边形边实体化节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形边实体化(ctx);
}

C_节点基类* f_node_载入多边形边实体化节点(S_设备环境& ctx, FILE* f) {
	C_多边形边实体化* node = new C_多边形边实体化(ctx);
	return node;
}

void f_node_保存多边形边实体化节点(C_节点基类* n, FILE* f) {
	C_多边形边实体化* node = dynamic_cast<C_多边形边实体化*>(n);
}





C_网格选择节点::C_网格选择节点(S_设备环境& ctx) : C_节点基类(DEF_网格选择节点) {
	m_Name = L"选择元素";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建网格_1D插座_I(L"网格");
	//DEF_创建UI32_1D插座_I(L"索引");
	DEF_创建元素数组选择插座_O(L"网格元素");

	m_选择类型 = f_alloc_EnumProp(nullptr, { {L"点", ""}, {L"线", ""}, {L"面", ""}, {L"元素", ""} }, L"选择类型", 2);
	m_选择类型.m_私有 = true;
}

C_网格选择节点::~C_网格选择节点() {
	auto* mesh = DEF_网格插座_1D数据(f_get输入插座(1), 0);
	auto* 元素选择 = DEF_元素数组选择插座数据(f_get输出插座(1), 0);

	//auto* socket2 = f_get输入插座(2);
	f_array_元素选择数组_resize(元素选择, mesh->count);

	for (uint32 i = 0; i < mesh->count; ++i) {
		元素选择->elementArray[i]->Type = E_值类型::e_Type_Mesh;
		元素选择->elementArray[i]->Element = mesh->ptr_userData[i];
		元素选择->elementArray[i]->Index;
	}
}

bool C_网格选择节点::f_update() {
	return false;
}

void C_网格选择节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_选择类型, f);
}

void C_网格选择节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_选择类型, f);
}

C_节点基类* f_node_创建网格选择节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_网格选择节点(ctx);
}

C_节点基类* f_node_载入网格选择节点(S_设备环境& ctx, FILE* f) {
	C_网格选择节点* node = new C_网格选择节点(ctx);
	return node;
}

void f_node_保存网格选择节点(C_节点基类* n, FILE* f) {
	C_网格选择节点* node = dynamic_cast<C_网格选择节点*>(n);
}





C_从索引构建面纹理坐标节点::C_从索引构建面纹理坐标节点(S_设备环境& ctx) : C_节点基类(DEF_从索引构建面纹理坐标节点)  {
	m_Name = L"索引构建UV";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形元素插座_I(L"面");
	DEF_创建uVec2插座_I(L"索引");
	DEF_创建UI32插座_I(L"层");

	DEF_创建多边形元素插座_O(L"面");

}

C_从索引构建面纹理坐标节点::~C_从索引构建面纹理坐标节点() {
}

bool C_从索引构建面纹理坐标节点::f_update() {
	return false;
}

void C_从索引构建面纹理坐标节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}

void C_从索引构建面纹理坐标节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

std::string	C_从索引构建面纹理坐标节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	m_Code += DEF_S(S_UI32Array);
	m_Code += " " + name + ";\n";
	m_Code += "{\n";

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);

	m_Code += name + " = ";
	m_Code += DEF_S(f_surface_从索引构纹理面坐标);
	m_Code += "(g多边形," + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ");\n";
	
	m_Code += m_ReleaseCode;
	m_Code += "}\n";


	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}

	return m_Code;
}

C_节点基类* f_node_创建构建面纹理坐标节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_从索引构建面纹理坐标节点(ctx);
}

C_节点基类* f_node_载入构建面纹理坐标节点(S_设备环境& ctx, FILE* f) {
	C_从索引构建面纹理坐标节点* node = new C_从索引构建面纹理坐标节点(ctx);
	return node;
}

void f_node_保存构建面纹理坐标节点(C_节点基类* n, FILE* f) {
	C_从索引构建面纹理坐标节点* node = dynamic_cast<C_从索引构建面纹理坐标节点*>(n);
}





C_设置多边形面属性节点::C_设置多边形面属性节点(S_设备环境& ctx) : C_节点基类(DEF_设置多边形面属性节点) {
	m_Name = L"多边形属性";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形面插座_I(L"面");
	DEF_创建Vec3_1D插座_I(L"点");

	DEF_创建多边形面插座_O(L"面");

	m_属性 = f_alloc_EnumProp(nullptr, {
		{L"坐标", ""},
		{L"法线", ""},
		//{L"面", ""},
		}, L"元素");
	m_属性.m_私有 = true;

}

C_设置多边形面属性节点::~C_设置多边形面属性节点() {
	f_prop_Release(m_属性);
}

bool C_设置多边形面属性节点::f_update() {
	return false;
}

std::string	C_设置多边形面属性节点::DEF_节点编译函数 {
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	//m_Code += DEF_S(S_Vec3Array*)" " + name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec3_1D, "1") + ";\n";
	m_Code += "{\n";

	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);

	switch (f_prop_enum(m_属性)) {
	case 0: {
		m_Code += DEF_S(f_surface_设置面顶点)"(g多边形," + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
		break;
	}
	case 1: {
		m_Code += DEF_S(f_surface_设置面法线)"(g多边形," + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
		break;
	}
	case 2: {
		m_Code += DEF_S(f_surface_设置面中心)"(g多边形," + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
		break;
	}
	case 3: {
		m_Code += DEF_S(f_surface_设置面顶点法线)"(g多边形," + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
		break;
	}
	}
	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(socket1->f_getCode(0));
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}

	return m_Code;
}

void C_设置多边形面属性节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_属性, f);
}

void C_设置多边形面属性节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Load(m_属性, f);
}

C_节点基类* f_node_创建设置多边形属性节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_设置多边形面属性节点(ctx);
}

C_节点基类* f_node_载入设置多边形属性节点(S_设备环境& ctx, FILE* f) {
	C_设置多边形面属性节点* node = new C_设置多边形面属性节点(ctx);
	return node;
}

void f_node_保存设置多边形属性节点(C_节点基类* n, FILE* f) {
	C_设置多边形面属性节点* node = dynamic_cast<C_设置多边形面属性节点*>(n);
}




C_设置多边形面UV节点::C_设置多边形面UV节点(S_设备环境& ctx) : C_节点基类(DEF_设置多边形面UV节点) {
	m_Name = L"设置面UV";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形元素插座_I(L"元素");
	DEF_创建uVec2_1D插座_I(L"环");
	DEF_创建UI32插座_I(L"层");

	DEF_创建多边形元素插座_O(L"元素");
}

C_设置多边形面UV节点::~C_设置多边形面UV节点() {
}

bool C_设置多边形面UV节点::f_update() {
	return false;
}

std::string	C_设置多边形面UV节点::DEF_节点编译函数 {
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	m_Code += "{\n";
	bool 多元素 = false;
	if (socket1->f_get接入的数据类型() == E_值类型::e_Type_多边形元素1D) {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_多边形元素1D);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_多边形元素1D);
		多元素 = true;
	}
	else {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_多边形元素);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_多边形元素);
	}
	socket1 = f_get输入插座(1);
	socket2 = f_get输入插座(2);
	socket3 = f_get输入插座(3);

	//m_Code += DEF_S(S_Vec3Array*)" " + name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec3_1D, "1") + ";\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);

	if (多元素) {
		m_Code += DEF_S(f_surface_设置元素组UV环)"(g多边形, " + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ");\n";
	}
	else {
		m_Code += DEF_S(f_surface_设置元素UV环)"(g多边形, " + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ");\n";
	}
	
	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(socket1->f_getCode(0));
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}

	return m_Code;
}

void C_设置多边形面UV节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	//f_prop_Load(m_属性, f);
}

void C_设置多边形面UV节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	//f_prop_Load(m_属性, f);
}

C_节点基类* f_node_创建设置多边形面UV节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_设置多边形面UV节点(ctx);
}

C_节点基类* f_node_载入设置多边形面UV节点(S_设备环境& ctx, FILE* f) {
	C_设置多边形面UV节点* node = new C_设置多边形面UV节点(ctx);
	return node;
}

void		f_node_保存设置多边形面UV节点(C_节点基类* n, FILE* f) {
	C_设置多边形面UV节点* node = dynamic_cast<C_设置多边形面UV节点*>(n);
}




C_多边形复制节点::C_多边形复制节点(S_设备环境& ctx) : C_节点基类(DEF_多边形复制节点) {
	m_Name = L"复制多边形元素";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形元素插座_I(L"元素");
	DEF_创建Vec3_1D插座_I(L"移动");
	DEF_创建Vec3_1D插座_I(L"旋转");
	DEF_创建Vec3_1D插座_I(L"缩放");
	DEF_创建UI32插座_I(L"数量");

	DEF_创建多边形元素_1D插座_O(L"元素");


	DEF_Vec3插座_1D数据(f_get输入插座(4))->ptr_userData[0] = {1,1,1};

	m_合并类型 = f_alloc_EnumProp(nullptr, {
		{L"只输出新元素", ""},
		{L"合并已有元素", ""},
		//{L"面", ""},
							  }, L"合并类型");
	m_合并类型.m_私有 = true;
}

C_多边形复制节点::~C_多边形复制节点() {
	f_prop_Release(m_合并类型);
}

bool C_多边形复制节点::f_update() {
	return false;
}

std::string	C_多边形复制节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();

	f_su_插座类型切换到连入的插座类型(this, e_插座Type_输入, 1, E_值类型::e_Type_多边形元素);

	auto* socket1 = f_get输入插座(1);
	switch (socket1->m_Type) {
		case E_值类型::e_Type_多边形元素: {
			f_su_切换后端插座类型(this, e_插座Type_输出, 1, E_值类型::e_Type_多边形元素1D);
			m_Code += DEF_S(S_多边形元素Array*)" " + name + ";\n";
			break;
		}
		case E_值类型::e_Type_多边形: {
			f_su_切换后端插座类型(this, e_插座Type_输出, 1, E_值类型::e_Type_多边形);
			m_Code += DEF_S(S_多边形*)" " + name + ";\n";
			break;
		}
		default:
			break;
	}


	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);
	auto* socket4 = f_get输入插座(4);
	auto* socket5 = f_get输入插座(5);

	
	m_Code += "{\n";

	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);
	m_Code += socket4->f_构建变量代码(0);
	m_Code += socket5->f_构建变量代码(0);

	auto code1 = socket1->f_getCode(0);
	auto code2 = socket2->f_getCode(0);
	auto code3 = socket3->f_getCode(0);
	auto code4 = socket4->f_getCode(0);
	auto code5 = socket5->f_getCode(0);

	if (code1.empty() || code2.empty() || code3.empty() || code4.empty() || code5.empty()) {
		//m_编译成功 = false;
		return "";
	}

	m_Code += name + " = ";

	switch (socket1->m_Type) {
		case E_值类型::e_Type_多边形元素: {
			m_Code += DEF_S(f_多边形_复制)"(g多边形, " + socket1->f_getCode(0) + ", "
				+ socket2->f_getCode(0) + ", "
				+ socket3->f_getCode(0) + ", "
				+ socket4->f_getCode(0) + ", "
				+ socket5->f_getCode(0) + ", "
				+ f_代码构建_属性变量(m_合并类型, f_getThis节点树()) + ");\n";
			break;
		}
		case E_值类型::e_Type_多边形: {
			
			break;
		}
		default:
			break;
	}
	
	m_Code += m_ReleaseCode;
	m_Code += "}\n";


	f_get输出插座(1)->f_setCode(name);

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		//m_区域父节点->m_ReleaseCode += f_代码构建_销毁Array(name);
		return "";
	}
	//释放 += f_代码构建_销毁Array(name);
	return m_Code;
}

void C_多边形复制节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		if (f_file_版本对比(文件块, S_节点数据::g_低版本号_0, S_节点数据::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_合并类型, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_多边形复制节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_合并类型, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建多边形复制节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形复制节点(ctx);
}

C_节点基类* f_node_载入多边形复制节点(S_设备环境& ctx, FILE* f) {
	C_多边形复制节点* node = new C_多边形复制节点(ctx);
	return node;
}

void f_node_保存多边形复制节点(C_节点基类* n, FILE* f) {
	C_多边形复制节点* node = dynamic_cast<C_多边形复制节点*>(n);
}





C_多边形拷贝节点::C_多边形拷贝节点(S_设备环境& ctx) : C_节点基类(DEF_多边形拷贝节点) {
	m_Name = L"拷贝多边形";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形_1D插座_I(L"源");
	DEF_创建多边形_1D插座_I(L"目标");
	//DEF_创建多边形元素插座_I(L"元素");

	DEF_创建Vec3_1D插座_I(L"移动");
	DEF_创建Vec3_1D插座_I(L"旋转");
	DEF_创建Vec3_1D插座_I(L"缩放");
	//DEF_创建UI32插座_I(L"数量");


	DEF_创建多边形_1D插座_O(L"多边形");



	DEF_Vec3插座_1D数据(f_get输入插座(5))->ptr_userData[0] = { 1,1,1 };
}

C_多边形拷贝节点::~C_多边形拷贝节点() {
}

bool C_多边形拷贝节点::f_update() {
	return false;
}

std::string	C_多边形拷贝节点::DEF_节点编译函数{
	m_Code = "";
	m_ReleaseCode = "";
	std::string name = f_getName();

	//f_su_插座类型切换到连入的插座类型(this, e_插座Type_输入, 1, E_值类型::e_Type_多边形);
	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	auto* socket3 = f_get输入插座(3);
	auto* socket4 = f_get输入插座(4);
	auto* socket5 = f_get输入插座(5);
	//auto* socket6 = f_get输入插座(6);


	//m_Code += DEF_S(S_多边形Array*)" " + name + " = " + f_代码构建_创建数组(E_值类型::e_Type_多边形_1D, 0);
	m_Code += DEF_S(S_多边形Array*)" " + name + ";\n";
	

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	
	m_Code += socket3->f_构建变量代码(0);
	m_Code += socket4->f_构建变量代码(0);
	m_Code += socket5->f_构建变量代码(0);
	//m_Code += socket6->f_构建变量代码(0);

	auto code1 = socket1->f_getCode(0);
	auto code2 = socket2->f_getCode(0);
	auto code3 = socket3->f_getCode(0);
	auto code4 = socket4->f_getCode(0);
	auto code5 = socket5->f_getCode(0);
	//auto code6 = socket5->f_getCode(0);

	if (code1.empty() || code2.empty()) {
		//m_编译成功 = false;
		return "";
	}

	m_Code += name + " = " + DEF_S(f_surface_拷贝多边形)"("
		+ socket1->f_getCode(0) + ", "
		+ socket2->f_getCode(0) + ", "
		+ socket3->f_getCode(0) + ", "
		+ socket4->f_getCode(0) + ", "
		+ socket5->f_getCode(0)
		+ ");\n";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";


	f_get输出插座(1)->f_setCode(name);

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_多边形拷贝节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

	auto 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		if (f_file_版本对比(文件块, S_节点数据::g_低版本号_0, S_节点数据::g_文件版本号)) {
			//下一次读取数据指针 = f_prop_Load(m_计算类型, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_多边形拷贝节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	//f_prop_Save(m_计算类型, 块);
	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建拷贝多边形节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形拷贝节点(ctx);
}
C_节点基类* f_node_载入拷贝多边形节点(S_设备环境& ctx, FILE* f) {
	C_多边形拷贝节点* node = new C_多边形拷贝节点(ctx);
	return node;
}
void f_node_保存拷贝多边形节点(C_节点基类* n, FILE* f) {
	C_多边形拷贝节点* node = dynamic_cast<C_多边形拷贝节点*>(n);
}




C_多边形变换节点::C_多边形变换节点(S_设备环境& ctx) : C_节点基类(DEF_多边形变换节点) {
	m_Name = L"变换多边形";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形插座_I(L"元素");
	DEF_创建Vec3插座_I(L"移动", nullptr);
	DEF_创建Vec3插座_I(L"旋转", nullptr);
	DEF_创建Vec3插座_I(L"缩放", nullptr);

	DEF_创建多边形插座_O(L"元素");
}

C_多边形变换节点::~C_多边形变换节点() {
}

bool C_多边形变换节点::f_update() {
	return false;
}

std::string	C_多边形变换节点::DEF_节点编译函数 {
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();


	f_su_插座类型切换到连入的插座类型(this, e_插座Type_输入, 1, E_值类型::e_Type_多边形);
	auto* socket1 = f_get输入插座(1);

	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);
	auto* socket4 = f_get输入插座(4);


	switch (socket1->m_Type) {
		case  E_值类型::e_Type_多边形: {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_多边形);

			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec3);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 3, E_值类型::e_Type_Vec3);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 4, E_值类型::e_Type_Vec3);
			break;
		}
		case  E_值类型::e_Type_多边形元素: {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_多边形元素);

			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec3);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 3, E_值类型::e_Type_Vec3);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 4, E_值类型::e_Type_Vec3);
			break;
		}
		case  E_值类型::e_Type_多边形元素1D: {
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_多边形元素1D);

			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 2, E_值类型::e_Type_Vec3_1D);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 3, E_值类型::e_Type_Vec3_1D);
			f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 4, E_值类型::e_Type_Vec3_1D);
			break;
		}
	}
	
	//m_Code += DEF_S(S_Vec3Array*)" " + name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec3_1D, "1") + ";\n";

	m_Code += "{\n";

	m_Code += socket1->f_构建变量代码(0);

	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);
	m_Code += socket4->f_构建变量代码(0);

	switch (socket1->m_Type) {
		case  E_值类型::e_Type_多边形: {
			m_Code += DEF_S(f_surface_多边形变换);
			break;
		}
		case  E_值类型::e_Type_多边形元素: {
			m_Code += DEF_S(f_surface_多边形元素变换);
			break;
		}
		case  E_值类型::e_Type_多边形元素1D: {
			m_Code += DEF_S(f_surface_多边形元素组变换);
			break;
		}
	}
	m_Code += "(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ", " + socket4->f_getCode(0) + ");\n";
	

	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(socket1->f_getCode(0));
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}

	return m_Code;
}

void C_多边形变换节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		if (f_file_版本对比(文件块, S_节点数据::g_低版本号_0, S_节点数据::g_文件版本号)) {
			//下一次读取数据指针 = f_prop_Load(m_外部加载, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_多边形变换节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	//f_prop_Save(m_外部加载, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建多边形变换节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形变换节点(ctx);
}

C_节点基类* f_node_载入多边形变换节点(S_设备环境& ctx, FILE* f) {
	C_多边形变换节点* node = new C_多边形变换节点(ctx);
	return node;
}

void f_node_保存多边形变换节点(C_节点基类* n, FILE* f) {
	C_多边形变换节点* node = dynamic_cast<C_多边形变换节点*>(n);
}








C_多边形四元数变换节点::C_多边形四元数变换节点(S_设备环境& ctx) : C_节点基类(DEF_多边形四元数变换节点) {
	m_Ctx = ctx;
	m_Name = L"面四元数变换";

	C_插座基类* socket;
	DEF_创建多边形元素插座_I(L"元素");
	DEF_创建Vec4插座_I(L"移动", nullptr);
	DEF_创建多边形元素插座_O(L"元素");
}

C_多边形四元数变换节点::~C_多边形四元数变换节点() {
}
bool C_多边形四元数变换节点::f_update() {
	auto& inData1 = *DEF_引用插座数据(f_get输入插座(1), 0);
	auto& inData2 = *DEF_引用插座数据(f_get输入插座(2), 0);
	auto& outData = *DEF_网格插座数据(f_get输出插座(1), 0);

	return false;
}

std::string	C_多边形四元数变换节点::DEF_节点编译函数 {
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	if (socket1->f_get接入的数据类型() == E_值类型::e_Type_多边形元素1D) {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_多边形元素1D);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_多边形元素1D);
	}
	else {
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, 1, E_值类型::e_Type_多边形元素);
		f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, 1, E_值类型::e_Type_多边形元素);
	}

	f_get输出插座(1)->f_setCode(socket1->f_getCode(0));
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}

	return m_Code;
}
void C_多边形四元数变换节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
}
void C_多边形四元数变换节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
}

C_节点基类* f_node_创建多边形四元数变换节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形四元数变换节点(ctx);
}

C_节点基类* f_node_载入多边形四元数变换节点(S_设备环境& ctx, FILE* f) {
	C_多边形四元数变换节点* node = new C_多边形四元数变换节点(ctx);
	return node;
}
void f_node_保存多边形四元数变换节点(C_节点基类* n, FILE* f) {
	C_多边形四元数变换节点* node = dynamic_cast<C_多边形四元数变换节点*>(n);
}




C_取多边形元素节点::C_取多边形元素节点(S_设备环境& ctx) : C_节点基类(DEF_取多边形顶点元素节点, E_节点类型::e_节点Type_多边形) {
	m_Ctx = ctx;
	m_Name = L"多边形元素";

	C_插座基类* socket;
	DEF_创建多边形插座_I(L"多边形");
	
	DEF_创建Vec3_1D插座_O(L"顶点");
	DEF_创建Vec3_1D插座_O(L"法线");
	DEF_创建多边形元素_1D插座_O(L"元素组");

}

C_取多边形元素节点::~C_取多边形元素节点() {
}

bool C_取多边形元素节点::f_update() {
	return false;
}

std::string	C_取多边形元素节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);


	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

C_节点基类* f_node_创建取多边形元素节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取多边形元素节点(ctx);
}

C_节点基类* f_node_载入取多边形元素节点(S_设备环境& ctx, FILE* f) {
	C_取多边形元素节点* node = new C_取多边形元素节点(ctx);
	return node;
}

void f_node_保存取多边形元素节点(C_节点基类* n, FILE* f) {
	C_取多边形元素节点* node = dynamic_cast<C_取多边形元素节点*>(n);
}




C_取多边形面节点::C_取多边形面节点(S_设备环境& ctx) : C_节点基类(DEF_取多边形顶点元素节点, E_节点类型::e_节点Type_多边形) {
	m_Ctx = ctx;
	m_Name = L"多边形元素";

	C_插座基类* socket;
	DEF_创建多边形元素插座_I(L"元素");

	DEF_创建多边形面插座_O(L"面");
}

C_取多边形面节点::~C_取多边形面节点() {
}

bool C_取多边形面节点::f_update() {
	return false;
}

std::string	C_取多边形面节点::DEF_节点编译函数 {
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);


	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

C_节点基类* f_node_创建取多边形面节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取多边形面节点(ctx);
}

C_节点基类* f_node_载入取多边形面节点(S_设备环境& ctx, FILE* f) {
	C_取多边形面节点* node = new C_取多边形面节点(ctx);
	return node;
}

void f_node_保存取多边形面节点(C_节点基类* n, FILE* f) {
	C_取多边形面节点* node = dynamic_cast<C_取多边形面节点*>(n);
}







C_取多边形面属性节点::C_取多边形面属性节点(S_设备环境& ctx) : C_节点基类(DEF_取多边形面属性节点) {
	m_Name = L"多边形属性";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形面插座_I(L"面");
	DEF_创建Vec3_1D插座_O(L"点");


	m_属性 = f_alloc_EnumProp(nullptr, {
		{L"顶点坐标", ""},
		{L"顶点法线", ""},
		//{L"面法线", ""},
		//{L"面中心", ""},
		
		//{L"面", ""},
		}, L"元素");
	m_属性.m_私有 = true;
}

C_取多边形面属性节点::~C_取多边形面属性节点() {
	f_prop_Release(m_属性);
}

bool C_取多边形面属性节点::f_update() {

	return false;
}

std::string	C_取多边形面属性节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);


	m_Code += DEF_S(S_Vec3Array*)" " + name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec3_1D, "1") + ";\n";
	m_Code += "{\n";

	m_Code += socket1->f_构建变量代码(0);

	switch (f_prop_enum(m_属性)) {
	case 0: {
		m_Code += DEF_S(f_surface_取面顶点)"(g多边形," + socket1->f_getCode(0) + ", " + name + ");\n";
		break;
	}
	case 1: {
		m_Code += DEF_S(f_surface_取面法线)"(g多边形," + socket1->f_getCode(0) + ", " + name + ");\n";
		break;
	}
	case 2: {
		m_Code += DEF_S(f_surface_取面中心)"(g多边形," + socket1->f_getCode(0) + ", " + name + ");\n";
		break;
	}
	case 3: {
		m_Code += DEF_S(f_surface_取面顶点法线)"(g多边形," + socket1->f_getCode(0) + ", " + name + ");\n";
		break;
	}
	}
	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_取多边形面属性节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_属性, f);
}

void C_取多边形面属性节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Load(m_属性, f);
}

C_节点基类* f_node_创建取多边形属性节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取多边形面属性节点(ctx);
}

C_节点基类* f_node_载入取多边形属性节点(S_设备环境& ctx, FILE* f) {
	C_取多边形面属性节点* node = new C_取多边形面属性节点(ctx);
	return node;
}

void f_node_保存取多边形属性节点(C_节点基类* n, FILE* f) {
	C_取多边形面属性节点* node = dynamic_cast<C_取多边形面属性节点*>(n);
}






C_取多边形面顶点节点::C_取多边形面顶点节点(S_设备环境& ctx) : C_节点基类(DEF_取多边形面顶点节点, E_节点类型::e_节点Type_多边形) {
	m_Name = L"取多边形点";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形面插座_I(L"面");
	DEF_创建Vec3_1D插座_O(L"点");


	m_属性 = f_alloc_EnumProp(nullptr, {
			{L"顶点坐标", ""},
			{L"顶点法线", ""},
			{L"面法线", ""},
			{L"面中心", ""},

			//{L"面", ""},
							}, L"元素");
	m_属性.m_私有 = true;

}

C_取多边形面顶点节点::~C_取多边形面顶点节点() {
}

bool C_取多边形面顶点节点::f_update() {
	return false;
}

void C_取多边形面顶点节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		if (f_file_版本对比(文件块, S_节点数据::g_低版本号_0, S_节点数据::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_属性, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_取多边形面顶点节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_属性, 块);

	f_file_保存文件块(f, 文件块, 块);
}

std::string	C_取多边形面顶点节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);

	m_Code += DEF_S(S_Vec3Array*)" " + name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec3_1D, "1") + ";\n";
	m_Code += "{\n";

	m_Code += socket1->f_构建变量代码(0);
	m_Code += "switch(" + f_代码构建_属性变量(m_属性, f_getThis节点树()) + "){\n";
	m_Code += "case 0 : " DEF_S(f_surface_取面顶点)"(" + socket1->f_getCode(0) + ", " + name + "); break;\n";
	m_Code += "case 1 : " DEF_S(f_surface_取面顶点法线)"(" + socket1->f_getCode(0) + ", " + name + "); break;\n";
	m_Code += "case 2 : " DEF_S(f_surface_取面法线)"(" + socket1->f_getCode(0) + ", " + name + "); break;\n";
	m_Code += "case 3 : " DEF_S(f_surface_取面中心)"(" + socket1->f_getCode(0) + ", " + name + "); break;\n";
	m_Code += "}\n";

	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

C_节点基类* f_node_创建取多边形面顶点节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取多边形面顶点节点(ctx);
}
C_节点基类* f_node_载入取多边形面顶点节点(S_设备环境& ctx, FILE* f) {
	C_取多边形面顶点节点* node = new C_取多边形面顶点节点(ctx);
	return node;
}
void		f_node_保存取多边形面顶点节点(C_节点基类* n, FILE* f) {
	C_取多边形面顶点节点* node = dynamic_cast<C_取多边形面顶点节点*>(n);
}






C_设置多边形面顶点节点::C_设置多边形面顶点节点(S_设备环境& ctx) : C_节点基类(DEF_设置多边形面顶点节点, E_节点类型::e_节点Type_多边形) {
	m_Name = L"设置多边形属性";
	m_Ctx = ctx;

	C_插座基类* socket;
	//DEF_创建多边形插座_I(L"多边形");
	DEF_创建多边形面插座_I(L"面");
	DEF_创建Vec3_1D插座_I(L"点");

	DEF_创建多边形面插座_O(L"面");

	m_属性 = f_alloc_EnumProp(nullptr, {
			{L"顶点坐标", ""},
			{L"顶点法线", ""},
			//{L"面法线", ""},
			//{L"面中心", ""},

			//{L"面", ""},
							}, L"元素");
	m_属性.m_私有 = true;

}

C_设置多边形面顶点节点::~C_设置多边形面顶点节点() {
}

bool C_设置多边形面顶点节点::f_update() {
	return false;
}

std::string	C_设置多边形面顶点节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	//m_Code += DEF_S(S_Vec3Array*)" " + name + " " + f_代码构建_创建Array(E_值类型::e_Type_Vec3_1D, "1") + ";\n";
	m_Code += "{\n";

	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);

	m_Code += "switch(" + f_代码构建_属性变量(m_属性, f_getThis节点树()) + "){\n";
	m_Code += "case 0 : " DEF_S(f_surface_设置面顶点)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + "); break;\n";
	m_Code += "case 1 : " DEF_S(f_surface_设置面顶点法线)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + "); break;\n";
	//m_Code += "case 2 : " DEF_S(f_surface_取面法线)"(" + socket1->f_getCode() + ", " + name + "); break;\n";
	//m_Code += "case 3 : " DEF_S(f_surface_取面中心)"(" + socket1->f_getCode() + ", " + name + "); break;\n";
	m_Code += "}\n";

	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(socket1->f_getCode(0));
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_设置多边形面顶点节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		if (f_file_版本对比(文件块, S_节点数据::g_低版本号_0, S_节点数据::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_属性, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_设置多边形面顶点节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_属性, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建设置多边形面顶点节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_设置多边形面顶点节点(ctx);
}
C_节点基类* f_node_载入设置多边形面顶点节点(S_设备环境& ctx, FILE* f) {
	C_设置多边形面顶点节点* node = new C_设置多边形面顶点节点(ctx);
	return node;
}
void		f_node_保存设置多边形面顶点节点(C_节点基类* n, FILE* f) {
	C_设置多边形面顶点节点* node = dynamic_cast<C_设置多边形面顶点节点*>(n);
}





C_取多边形面UV节点::C_取多边形面UV节点(S_设备环境& ctx) : C_节点基类(DEF_取多边形顶点元素节点, E_节点类型::e_节点Type_多边形) {
	
}

C_取多边形面UV节点::~C_取多边形面UV节点() {
	
}

bool C_取多边形面UV节点::f_update() {
	return false;
}

void C_取多边形面UV节点::f_读取(FILE* f) {
	
}

void C_取多边形面UV节点::f_写入(FILE* f) {
	
}

std::string	C_取多边形面UV节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);


	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

C_节点基类* f_node_创建取多边形面UV节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取多边形面UV节点(ctx);
}
C_节点基类* f_node_载入取多边形面UV节点(S_设备环境& ctx, FILE* f) {
	C_取多边形面UV节点* node = new C_取多边形面UV节点(ctx);
	return node;
}
void		f_node_保存取多边形面UV节点(C_节点基类* n, FILE* f) {
	C_取多边形面UV节点* node = dynamic_cast<C_取多边形面UV节点*>(n);
}






C_取多边形_边::C_取多边形_边(S_设备环境& ctx) : C_节点基类(DEF_取多边形边节点, E_节点类型::e_节点Type_多边形) {
	m_Name = L"取多边形边";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形插座_I(L"多边形");
	DEF_创建UI32插座_I(L"边ID");
	DEF_创建多边形边插座_O(L"边");

}

C_取多边形_边::~C_取多边形_边() {
}

bool C_取多边形_边::f_update() {
	auto* socket1 = f_get输出插座(1);
	S_边* 边 = f_surface_取多边形边(DEF_多边形插座数据(f_get输入插座(1)), DEF_UI32插座数据(f_get输入插座(2)));
	socket1->f_setData(边);
	return false;
}

std::string	C_取多边形_边::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	m_Code += DEF_S(S_边*)" " + name + ";\n";
	m_Code += "{\n";

	m_Code += socket1->f_构建变量代码(0);

	m_Code += name + " = " + DEF_S(f_surface_取多边形边)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
	
	m_Code += "}\n";


	f_get输出插座(1)->f_setCode(name);

	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		return "";
	}
	return m_Code;
}

void C_取多边形_边::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		//下一次读取数据指针 = f_prop_Load(m_是否改变原数据, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_取多边形_边::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	//f_prop_Save(m_是否改变原数据, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);

	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建取多边形_边节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取多边形_边(ctx);
}
C_节点基类* f_node_载入取多边形_边节点(S_设备环境& ctx, FILE* f) {
	C_取多边形_边* node = new C_取多边形_边(ctx);
	return node;
}
void f_node_保存取多边形_边节点(C_节点基类* n, FILE* f) {
	C_取多边形_边* node = dynamic_cast<C_取多边形_边*>(n);
}



C_取多边形_元素::C_取多边形_元素(S_设备环境& ctx) : C_节点基类(DEF_取多边形面元素节点) {
	m_Name = L"取多边形元素";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建多边形插座_I(L"多边形");
	DEF_创建UI32_1D插座_I(L"索引");

	DEF_创建多边形元素_1D插座_O(L"元素");
}

C_取多边形_元素::~C_取多边形_元素() {
	
}

bool C_取多边形_元素::f_update() {
	return false;
}

std::string	C_取多边形_元素::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	

	
	auto* socket1 = f_get输入插座(1);
	if (!socket1->f_isLink()) {
		return "";
	}

	std::string name = f_getName();
	bool 创建数组 = false;

	f_su_插座类型切换到连入的插座类型(this, e_插座Type_输入, 2, E_值类型::e_Type_UI32);


	auto* socket2 = f_get输入插座(2);
	switch (socket2->m_Type) {
		case E_值类型::e_Type_UI32: {
			f_su_插座类型切换到连入的插座类型(this, e_插座Type_输出, 1, E_值类型::e_Type_多边形元素);
			//m_Code += DEF_S(S_多边形元素*)" " + name + ";\n";
			m_Code += DEF_S(S_多边形元素*)" " + name + " = " + f_代码构建_创建数组(E_值类型::e_Type_多边形元素, 0);
			break;
		}
		case E_值类型::e_Type_UI32_1D: {
			f_su_插座类型切换到连入的插座类型(this, e_插座Type_输出, 1, E_值类型::e_Type_多边形元素1D);
			//m_Code += DEF_S(S_多边形元素Array*)" " + name + ";\n";
			m_Code += DEF_S(S_多边形元素Array*)" " + name + " = " + f_代码构建_创建数组(E_值类型::e_Type_多边形元素1D, 0);
			创建数组 = true;
			break;
		}
		default:
			break;
	}
	
	

	m_Code += "{\n";
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);

	switch (socket2->m_Type) {
		case E_值类型::e_Type_UI32: {
			m_Code += name + " = " + DEF_S(f_surface_取多边形元素)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ");\n";
			break;
		}
		case E_值类型::e_Type_UI32_1D: {
			m_Code += DEF_S(f_surface_取多边形多个元素)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + name + ");\n";
			break;
		}
	}

	m_Code += m_ReleaseCode;
	m_Code += "}\n";



	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;

		if (创建数组) {
			m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		}
		return "";
	}
	if (创建数组) {
		释放 += f_代码构建_销毁数组(name);
	}
	return m_Code;
}

void C_取多边形_元素::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		if (f_file_版本对比(文件块, S_节点数据::g_低版本号_0, S_节点数据::g_文件版本号)) {
			//下一次读取数据指针 = f_prop_Load(m_是否改变原数据, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_取多边形_元素::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	//f_prop_Save(m_是否改变原数据, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建取多边形_元素节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取多边形_元素(ctx);
}
C_节点基类* f_node_载入取多边形_元素节点(S_设备环境& ctx, FILE* f) {
	C_取多边形_元素* node = new C_取多边形_元素(ctx);
	return node;
}
void		f_node_保存取多边形_元素节点(C_节点基类* n, FILE* f) {
	C_取多边形_元素* node = dynamic_cast<C_取多边形_元素*>(n);
}




C_多边形转网格节点::C_多边形转网格节点(S_设备环境& ctx) : C_节点基类(DEF_多边形转网格节点, E_节点类型::e_节点Type_多边形) {
	m_Name = L"多边形转网格";
	m_Ctx = ctx;

	C_插座基类* socket;
	//DEF_创建多边形插座_I(L"多边形");
	DEF_创建物体_1D插座_I(L"物体");
	DEF_创建物体_1D插座_O(L"物体");
	//DEF_创建多边形面插座_O(L"面");



}

C_多边形转网格节点::~C_多边形转网格节点() {

}

bool C_多边形转网格节点::f_update() {
	auto* ob = DEF_物体插座_1D数据(f_get输入插座(1), 0);

#pragma omp parallel for
	for (int32 i = 0; i < ob->count; ++i) {
		f_NE_多边形转网格(ob->ptr_userData[i], f_prop_Bool(m_平滑法线));
	}

	f_get输出插座(1)->f_setData(ob);
	//auto* ob = DEF_物体插座_1D数据(f_get输出插座(1), 0);
	return false;
}

void C_多边形转网格节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);

}

void C_多边形转网格节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

}

C_节点基类* f_node_创建多边形转网格节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_多边形转网格节点(ctx);
}

C_节点基类* f_node_载入多边形转网格节点(S_设备环境& ctx, FILE* f) {
	C_多边形转网格节点* node = new C_多边形转网格节点(ctx);
	return node;
}

void		f_node_保存多边形转网格节点(C_节点基类* n, FILE* f) {
	C_多边形转网格节点* node = dynamic_cast<C_多边形转网格节点*>(n);
}



C_取网格元素节点::C_取网格元素节点(S_设备环境& ctx) : C_节点基类(DEF_取网格元素节点, E_节点类型::e_节点Type_多边形) {
	m_Name = L"取网格元素";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建物体插座_I(L"网格");
	DEF_创建UI32_2D插座_O(L"索引");


	m_元素类型 = f_alloc_EnumProp(nullptr, {
												{L"顶点坐标", ""},
												{L"顶点法线", ""},

											 }, L"元素");
	m_元素类型.m_私有 = true;

	
}

C_取网格元素节点::~C_取网格元素节点() {
	f_prop_Release(m_元素类型);
}

bool C_取网格元素节点::f_update() {
	auto* ob = DEF_物体插座数据(f_get输入插座(1), 0);
	auto* 元素索引 = DEF_UI32插座_2D数据(f_get输出插座(1));

	f_array_释放UI32_2D(元素索引);

	if (ob && ob->m_UserData) {
		S_多边形* 多边形 = ((S_多边形*)ob->m_UserData);
		uint32 num = 多边形->m_元素组->count;
		
		f_core_array_resize((S_Array*)元素索引, num);
		for (uint32 i = 0; i < num; ++i) {
			S_多边形元素* 多边形元素 = 多边形->m_元素组->ptr_userData[i];

			元素索引->ptr_userData[i] = (S_UI32Array*)f_core_array_new(0, sizeof(uint32));

			uint32 面数量 = 多边形元素->count;
			for (uint32 j = 0; j < 面数量; ++j) {
				uint32 顶点数量 = 多边形元素->ptr_userData[j]->vertIndex.size();
				auto* 顶点索引 = 多边形元素->ptr_userData[j]->vertIndex.data();

				f_core_array_push_back_block((S_Array*)元素索引->ptr_userData[i], (uint8*)顶点索引, 顶点数量, sizeof(uint32));
			}
			
		}

		f_mesh_清除网格元素中相同索引(元素索引);
	}

	return false;
}

void C_取网格元素节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		f_prop_Load(m_元素类型, 下一次读取数据指针);
	}
	
	free(文件块.m_data);
}

void C_取网格元素节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, 0|0);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_元素类型, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);

	f_core_array_free((S_Array*)块);
}

void C_取网格元素节点::f_getStr(std::vector<std::vector<std::wstring>>& 文本) {
	auto* 点 = DEF_UI32插座_2D数据(f_get输出插座(1));

	uint32 num = 点->count;
	for (uint32 i = 0; i < num; ++i) {
		uint32 面数量 = 点->ptr_userData[i]->count;
		uint32* index = 点->ptr_userData[i]->ptr_userData;

		std::vector<std::wstring> 面ID;
		for (uint32 j = 0; j < 面数量; ++j) {
			面ID.push_back(f_整数值转宽字符串(index[j]));
		}

		文本.push_back(面ID);
	}
}

C_节点基类* f_node_创建取网格元素节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取网格元素节点(ctx);
}

C_节点基类* f_node_载入取网格元素节点(S_设备环境& ctx, FILE* f) {
	C_取网格元素节点* node = new C_取网格元素节点(ctx);
	return node;
}

void		f_node_保存取网格元素节点(C_节点基类* n, FILE* f) {
	C_取网格元素节点* node = dynamic_cast<C_取网格元素节点*>(n);
}



C_取网格元素顶点节点::C_取网格元素顶点节点(S_设备环境& ctx) : C_节点基类(DEF_取网格元素顶点节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"取网格元素顶点";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建网格插座_I(L"网格");
	DEF_创建UI32_1D插座_I(L"元素");

	DEF_创建Vec3_1D插座_O(L"点");

	m_属性 = f_alloc_EnumProp(nullptr, {
										{L"顶点坐标", ""},
										{L"顶点法线", ""},

							  }, L"元素");
	m_属性.m_私有 = true;
}

C_取网格元素顶点节点::~C_取网格元素顶点节点() {
	f_prop_Release(m_属性);
}

bool C_取网格元素顶点节点::f_update() {
	auto* vert = DEF_Vec3插座_1D数据(f_get输出插座(1));

	auto* mesh = DEF_网格插座数据(f_get输入插座(1));
	if (mesh) {
		auto* index = DEF_UI32插座_1D数据(f_get输入插座(2));
		f_surface_get网格顶点数据(mesh, index, vert, f_prop_enum(m_属性));
	}
	else {
		f_core_array_resize((S_Array*)vert, 0);
	}
	
	return false;
}

std::string	C_取网格元素顶点节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);

	m_Code += DEF_S(S_Vec3Array*)" " + name + " = " + f_代码构建_创建Array(E_值类型::e_Type_Vec3_1D, "1") + ";\n";
	m_Code += "{\n";

	auto 网格成员 = f_代码构建_属性变量(m_属性, f_getThis节点树());
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += DEF_S(f_surface_get网格顶点数据)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + name + ", " + 网格成员 + ");\n";
	
	m_Code += m_ReleaseCode;
	m_Code += "}\n";

	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		m_区域父节点->m_ReleaseCode += f_代码构建_销毁数组(name);
		return "";
	}
	释放 += f_代码构建_销毁数组(name);
	return m_Code;
}

void C_取网格元素顶点节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		f_prop_Load(m_属性, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_取网格元素顶点节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_属性, 块);

	f_file_保存文件块(f, 文件块, 块);
}

void C_取网格元素顶点节点::f_getStr(std::vector<std::vector<std::wstring>>& 文本) {
	auto* vert = DEF_Vec3插座_1D数据(f_get输出插座(1));

	uint32 num = vert->count;
	for (uint32 i = 0; i < num; ++i) {
		vec3 点 = vert->ptr_userData[i];

		std::vector<std::wstring> 顶点(3);
		顶点[0] = f_浮点数值转宽字符串(点.x);
		顶点[1] = f_浮点数值转宽字符串(点.y);
		顶点[2] = f_浮点数值转宽字符串(点.z);

		文本.push_back(顶点);
	}
}

C_节点基类* f_node_创建取网格元素顶点节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_取网格元素顶点节点(ctx);
}

C_节点基类* f_node_载入取网格元素顶点节点(S_设备环境& ctx, FILE* f) {
	C_取网格元素顶点节点* node = new C_取网格元素顶点节点(ctx);
	return node;
}

void		f_node_保存取网格元素顶点节点(C_节点基类* n, FILE* f) {
	C_取网格元素顶点节点* node = dynamic_cast<C_取网格元素顶点节点*>(n);
}




C_设置网格元素顶点节点::C_设置网格元素顶点节点(S_设备环境& ctx) : C_节点基类(DEF_设置网格元素顶点节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"设置网格元素顶点";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建网格插座_I(L"网格");
	DEF_创建UI32_1D插座_I(L"索引");
	DEF_创建Vec3_1D插座_I(L"点");
	//DEF_创建Vec3_1D插座_I(L"法线");
	
	DEF_创建网格插座_O(L"网格");

	m_属性 = f_alloc_EnumProp(nullptr, {
										{L"顶点坐标", ""},
										{L"顶点法线", ""},

							}, L"元素");
	m_属性.m_私有 = true;
}

C_设置网格元素顶点节点::~C_设置网格元素顶点节点() {
	f_prop_Release(m_属性);
}

bool C_设置网格元素顶点节点::f_update() {
	auto* mesh = DEF_网格插座数据(f_get输入插座(1));
	//auto* index = DEF_UI32插座_1D数据(f_get输入插座(2));
	if (mesh) {
		auto* index = DEF_UI32插座_1D数据(f_get输入插座(2));
		auto* vert = DEF_Vec3插座_1D数据(f_get输入插座(3));

		f_surface_set网格顶点数据(mesh, index, vert, f_prop_enum(m_属性));
	}
	else {
		//f_core_array_resize((S_Array*)vert, 0);
	}

	return false;
}

std::string	C_设置网格元素顶点节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	m_Code += "{\n";
	auto 网格成员 = f_代码构建_属性变量(m_属性, f_getThis节点树());
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);
	m_Code += DEF_S(f_surface_set网格顶点数据)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ", " + 网格成员 + ");\n";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";


	f_get输出插座(1)->f_setCode(socket1->f_getCode(0));
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;
		
		return "";
	}
	return m_Code;
}

void C_设置网格元素顶点节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		f_prop_Load(m_属性, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_设置网格元素顶点节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, 0 | 0);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_属性, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);

	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建设置网格元素顶点节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_设置网格元素顶点节点(ctx);
}

C_节点基类* f_node_载入设置网格元素顶点节点(S_设备环境& ctx, FILE* f) {
	C_设置网格元素顶点节点* node = new C_设置网格元素顶点节点(ctx);
	return node;
}

void		f_node_保存设置网格元素顶点节点(C_节点基类* n, FILE* f) {
	C_设置网格元素顶点节点* node = dynamic_cast<C_设置网格元素顶点节点*>(n);
}





C_网格顶点节点::C_网格顶点节点(S_设备环境& ctx) : C_节点基类(DEF_设置网格元素顶点节点, E_节点类型::e_节点Type_网格) {
	m_Name = L"设置网格元素顶点";
	m_Ctx = ctx;

	C_插座基类* socket;
	DEF_创建网格插座_I(L"网格");
	DEF_创建Vec3_1D插座_O(L"顶点");
	DEF_创建Vec3_1D插座_O(L"法线");
	DEF_创建Vec3_1D插座_O(L"UV");
	DEF_创建UI32_1D插座_O(L"索引");

	DEF_创建网格插座_O(L"网格");

	m_属性 = f_alloc_EnumProp(nullptr, {
										{L"顶点坐标", ""},
										{L"顶点法线", ""},

							}, L"元素");
	m_属性.m_私有 = true;
}

C_网格顶点节点::~C_网格顶点节点() {
	f_prop_Release(m_属性);
}

bool C_网格顶点节点::f_update() {
	auto* mesh = DEF_网格插座数据(f_get输入插座(1));
	//auto* index = DEF_UI32插座_1D数据(f_get输入插座(2));
	if (mesh) {
		auto* index = DEF_UI32插座_1D数据(f_get输入插座(2));
		auto* vert = DEF_Vec3插座_1D数据(f_get输入插座(3));

		f_surface_set网格顶点数据(mesh, index, vert, f_prop_enum(m_属性));
	}
	else {
		//f_core_array_resize((S_Array*)vert, 0);
	}

	return false;
}

std::string	C_网格顶点节点::DEF_节点编译函数{
	m_ReleaseCode = "";
	m_Code = "";
	std::string name = f_getName();

	auto* socket1 = f_get输入插座(1);
	auto* socket2 = f_get输入插座(2);
	auto* socket3 = f_get输入插座(3);

	m_Code += "{\n";
	auto 网格成员 = f_代码构建_属性变量(m_属性, f_getThis节点树());
	m_Code += socket1->f_构建变量代码(0);
	m_Code += socket2->f_构建变量代码(0);
	m_Code += socket3->f_构建变量代码(0);
	m_Code += DEF_S(f_surface_set网格顶点数据)"(" + socket1->f_getCode(0) + ", " + socket2->f_getCode(0) + ", " + socket3->f_getCode(0) + ", " + 网格成员 + ");\n";

	m_Code += m_ReleaseCode;
	m_Code += "}\n";


	f_get输出插座(1)->f_setCode(name);
	if (m_区域父节点) {
		m_区域父节点->m_Code += m_Code;

		return "";
	}
	return m_Code;
}

void C_网格顶点节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		f_prop_Load(m_属性, 下一次读取数据指针);
	}

	free(文件块.m_data);
}

void C_网格顶点节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点实例属性, 0 | 0);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_prop_Save(m_属性, 块);

	文件块.m_data = 块->ptr_userData;
	文件块.m_字节数 = 块->count;
	f_file_保存文件块(f, 文件块);

	f_core_array_free((S_Array*)块);
}

C_节点基类* f_node_创建网格顶点节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_网格顶点节点(ctx);
}

C_节点基类* f_node_载入网格顶点节点(S_设备环境& ctx, FILE* f) {
	C_网格顶点节点* node = new C_网格顶点节点(ctx);
	return node;
}

void		f_node_保存网格顶点节点(C_节点基类* n, FILE* f) {
	C_网格顶点节点* node = dynamic_cast<C_网格顶点节点*>(n);
}

